Merge branch 'release-1.1.0'
diff --git a/weinre.application/resources/macosx/weinre.app/Contents/Info.plist b/weinre.application/resources/macosx/weinre.app/Contents/Info.plist
index 19b2870..3e8310a 100644
--- a/weinre.application/resources/macosx/weinre.app/Contents/Info.plist
+++ b/weinre.application/resources/macosx/weinre.app/Contents/Info.plist
@@ -17,7 +17,7 @@
     <key>CFBundleIconFile</key>
         <string>weinre.icns</string>
     <key>CFBundleIdentifier</key>
-        <string>com.phonegap.weinre.application</string>
+        <string>weinre.application</string>
     <key>CFBundleInfoDictionaryVersion</key>
         <string>6.0</string>
     <key>CFBundleName</key>
diff --git a/weinre.application/resources/macosx/weinre.app/Contents/MacOS/launcher b/weinre.application/resources/macosx/weinre.app/Contents/MacOS/launcher
index 9259211..ffc287d 100644
--- a/weinre.application/resources/macosx/weinre.app/Contents/MacOS/launcher
+++ b/weinre.application/resources/macosx/weinre.app/Contents/MacOS/launcher
@@ -12,4 +12,4 @@
 java \
     -XstartOnFirstThread \
     -classpath $BASEDIR/weinre-ui.jar:$BASEDIR/weinre.jar:$BASEDIR/swt.jar \
-    com.phonegap.weinre.application.GUIMain
+    weinre.application.GUIMain
diff --git a/weinre.application/src/com/phonegap/weinre/application/GUIPreferences.java b/weinre.application/src/com/phonegap/weinre/application/GUIPreferences.java
deleted file mode 100644
index 196bcb2..0000000
--- a/weinre.application/src/com/phonegap/weinre/application/GUIPreferences.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.application;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Properties;
-
-import org.apache.wink.json4j.JSONException;
-import org.apache.wink.json4j.JSONObject;
-import org.eclipse.swt.widgets.Shell;
-
-import com.phonegap.weinre.server.Main;
-
-/**
- * 
- */
-public class GUIPreferences {
-    private Properties properties;
-    private String     fileName;
-    
-    /**
-     * 
-     */
-    public GUIPreferences() {
-        super();
-
-        properties = new Properties();
-        fileName   = null;
-        
-        String userHome = System.getProperty("user.home");
-        if (null == userHome) {
-            Main.warn("System property user.home not set!");
-            return;
-        }
-        
-        File dir = new File(userHome, ".weinre");
-        if (!dir.exists()) {
-            dir.mkdirs();
-        }
-        
-        File file = new File(dir, "ui.properties");
-        fileName = file.getAbsolutePath();
-        
-        if (!file.exists()) return;
-        
-        loadFromFile();
-    }
-
-    /**
-     * 
-     */
-    public String getBoundsKey(Shell shell, String name) {
-        return "bounds-" + name + "-" + ShellSizeTracker.getMonitorSetupKey(shell.getDisplay());        
-    }
-    
-    /**
-     * 
-     */
-    public void loadFromFile() {
-        properties.clear();
-        
-        try {
-            properties.load(new FileReader(fileName));
-        }
-        catch (IOException e) {
-            Main.warn("IOException reading '" + fileName + "': " + e);
-        }
-    }
-
-    /**
-     * 
-     */
-    public void saveToFile() {
-        if (null == fileName) return;
-        
-        try {
-            properties.store(new FileWriter(fileName), "ui settings");
-        }
-        catch (IOException e) {
-            Main.warn("IOException writing '" + fileName + "': " + e);
-        }
-    }
-    
-    /**
-     * 
-     */
-    public String getPreference(String key) {
-        if (null == properties) loadFromFile();
-        return properties.getProperty(key);
-    }
-    
-    /**
-     * 
-     */
-    public JSONObject getPreferenceFromJSON(String key) throws IOException {
-        String val = getPreference(key);
-        if (null == val) return null;
-
-        try {
-            return new JSONObject(val);
-        } catch (JSONException e) {
-            throw new RuntimeException(e);
-        }
-    }
-    
-    /**
-     * 
-     */
-    public void setPreference(String key, String val) {
-        properties.setProperty(key, val);
-    }
-
-    /**
-     * 
-     */
-    public void setPreference(String key, JSONObject json) throws IOException {
-        String val = json.toString();
-        
-        properties.setProperty(key, val);
-    }
-
-}
diff --git a/weinre.application/src/com/phonegap/weinre/application/GUIMain.java b/weinre.application/src/weinre/application/GUIMain.java
similarity index 78%
rename from weinre.application/src/com/phonegap/weinre/application/GUIMain.java
rename to weinre.application/src/weinre/application/GUIMain.java
index 18d3082..7ae91a4 100644
--- a/weinre.application/src/com/phonegap/weinre/application/GUIMain.java
+++ b/weinre.application/src/weinre/application/GUIMain.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.application;
+package weinre.application;
 
 import java.io.IOException;
 
@@ -29,41 +29,35 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 
-import com.phonegap.weinre.server.Main;
-import com.phonegap.weinre.server.ServerSettings;
+import weinre.server.Main;
+import weinre.server.ServerSettings;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class GUIMain extends Main {
-    private Display        display;
-    private Shell          shell;
-    private Browser        debugger;
-    private StyledText     console;
-    private Browser        homePage;
-    private Color          red;
-    private GUIPreferences preferences;
+    private Display          display;
+    private Shell            shell;
+    private Browser          debugger;
+    private StyledText       console;
+    private Browser          homePage;
+    private Color            red;
+    private GUIPreferences   preferences;
+    private ShellSizeTracker shellSizeTracker;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public void main(String[] args) {
         GUIMain main = new GUIMain(args);
         main.run();
     }
 
-    /**
-     * 
-     */
-    public GUIMain(String[] args) {
+    //---------------------------------------------------------------
+    private GUIMain(String[] args) {
         super(args);
         
         preferences = new GUIPreferences();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
+    @Override
     public void run() {
         uiBuild();
 
@@ -80,185 +74,23 @@
         exit();
     }
 
-    /**
-     * 
-     */
-    public GUIPreferences getPreferences() {
-        return preferences;
-    }
-    
-    /**
-     * 
-     */
-    public void uiBuild() {
-        Display.setAppName("weinre");
-        Display.setAppVersion("???");
-        
-        display = new Display();
-        shell   = new Shell(display);
-        
-        red = new Color(display, 255, 0, 0);
-
-        shell.setText("weinre - Web Inspector Remote");
-        
-        CTabFolder tabFolder       = new CTabFolder(shell, SWT.BORDER);
-        CTabItem   tabItemDebugger = createTabItem(tabFolder, "Debugger");
-        CTabItem   tabItemConsole  = createTabItem(tabFolder, "Server Console");
-        CTabItem   tabItemHomePage = createTabItem(tabFolder, "Server Home Page");
-
-        debugger = new Browser(tabFolder, SWT.NONE);
-        tabItemDebugger.setControl(debugger);
-        
-        console = new StyledText(tabFolder, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-        console.setEditable(false);
-        console.setFont(getMonospaceFont(console));
-
-        homePage = new Browser(tabFolder, SWT.NONE);
-        tabItemHomePage.setControl(homePage);
-        
-        tabItemConsole.setControl(console);
-        
-        fillParent(debugger,  0, 0, 0, 0);
-        fillParent(console,   0, 0, 0, 0);
-        fillParent(homePage,  0, 0, 0, 0);
-        fillParent(tabFolder, 5, 5, 5, 5);
-        
-        tabFolder.pack();
-        createMenuBar();
-        
-        new ShellSizeTracker("main", shell, preferences);
-        
-        try {
-            String       boundsKey = preferences.getBoundsKey(shell, "main");
-            JSONObject   bounds    = preferences.getPreferenceFromJSON(boundsKey);
-            
-            if (null != bounds) {
-                Integer x, y, w, h;
-                try {
-                    x = bounds.getInt("x");
-                    y = bounds.getInt("y");
-                    w = bounds.getInt("width");
-                    h = bounds.getInt("height");
-                } catch (JSONException e) {
-                    throw new RuntimeException(e);
-                }
-                
-                if ((null != w) && (null != h)) {
-                    shell.setBounds(x,y,w,h);
-                }
-            }
-            
-            else {
-                shell.setBounds(100, 100, 500, 300);
-            }
-            
-        }
-        catch (IOException e) {
-            Main.warn("exception reading preferences: " + e);
-        }
-        
-    }
- 
-    /**
-     * 
-     */
-    private void createMenuBar() {
-//        Menu menu = new Menu(shell, SWT.BAR);
-//        shell.setMenuBar(menu);
-//        MenuItem fileMenuItem = new MenuItem(menu, SWT.CASCADE);
-//        fileMenuItem.setText("File");
-//        MenuItem editMenuItem = new MenuItem(menu, SWT.CASCADE);
-//        editMenuItem.setText("Edit");
-     }        
-
-    /**
-     * 
-     */
-    public void uiRun() {
-        shell.open();
-        
-        while (!shell.isDisposed()) {
-            if (!display.readAndDispatch())
-                display.sleep();
-        }
-        display.dispose();
-    }
-
-    /**
-     * 
-     */
-    public CTabItem createTabItem(CTabFolder tabFolder, String text) {
-        CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE);
-        tabItem.setText(text);
-        
-        Font       font     = tabItem.getFont();
-        FontData[] fontData = font.getFontData();
-        
-        for (FontData fontDatum: fontData) {
-            double newHeight = fontDatum.getHeight() * 1.25;
-            fontDatum.setHeight((int) newHeight);
-        }
-        
-        font = new Font(display, fontData);
-        tabItem.setFont(font);
-        
-        return tabItem;
-    }
-    
-    /**
-     * 
-     */
-    public void fillParent(Control control, int marginT, int marginR, int marginB, int marginL ) {
-        FormLayout formLayout = new FormLayout();
-        
-        formLayout.marginTop    = marginT; 
-        formLayout.marginBottom = marginB;
-        formLayout.marginLeft   = marginL;
-        formLayout.marginRight  = marginR;
-        
-        FormData formData = new FormData();
-        
-        formData.left     = new FormAttachment(0);
-        formData.right    = new FormAttachment(100);
-        formData.top      = new FormAttachment(0);
-        formData.bottom   = new FormAttachment(100);
-
-        control.getParent().setLayout(formLayout);
-        control.setLayoutData(formData);
-    }
-    
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
+    @Override
     public void serverStarted() {
         debugger.getDisplay().asyncExec(new Runnable() {
             public void run() {
-                debugger.setUrl(getBrowserURL() + "client/index.html");
-                homePage.setUrl(getBrowserURL() + "index.html");
+                debugger.getDisplay().timerExec(1000, new Runnable() {
+                    public void run() {
+                        debugger.setUrl(getBrowserURL() + "client/index.html");
+                        homePage.setUrl(getBrowserURL() + "index.html");
+                    }
+                });
             }
         });
     }
-    
-    /**
-     * 
-     */
-    public String getBrowserURL() {
-        String result;
-        
-        ServerSettings settings = com.phonegap.weinre.server.Main.getSettings();
-        
-        String host = settings.getNiceHostName();
-        int    port = settings.getHttpPort();
-        
-        result = "http://" + host + ":" + port + "/";
-        
-        return result;
-    }
-    
-    
-    /**
-     * 
-     */
+
+    //---------------------------------------------------------------
+    @Override
     public void addServerConsoleMessage(final String line, final boolean stdout) {
         if (null == console) return;
         
@@ -284,10 +116,7 @@
         });
     }
     
-    
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     @Override
     public int severeError(final String message) {
         if (null == display) return super.severeError(message);
@@ -317,9 +146,152 @@
         return 0;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
+    private void uiBuild() {
+        Display.setAppName("weinre");
+        Display.setAppVersion("???");
+        
+        display = new Display();
+        shell   = new Shell(display);
+        
+        red = new Color(display, 255, 0, 0);
+
+        shell.setText("weinre - Web Inspector Remote");
+        
+        CTabFolder tabFolder       = new CTabFolder(shell, SWT.BORDER | SWT.BOTTOM);
+        CTabItem   tabItemDebugger = createTabItem(tabFolder, "Debugger");
+        CTabItem   tabItemConsole  = createTabItem(tabFolder, "Server Console");
+        CTabItem   tabItemHomePage = createTabItem(tabFolder, "Server Home Page");
+
+        debugger = new Browser(tabFolder, SWT.NONE);
+        tabItemDebugger.setControl(debugger);
+        
+        console = new StyledText(tabFolder, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+        console.setEditable(false);
+        console.setFont(getMonospaceFont(console));
+
+        homePage = new Browser(tabFolder, SWT.NONE);
+        tabItemHomePage.setControl(homePage);
+        
+        tabItemConsole.setControl(console);
+        
+        fillParent(debugger,  0, 0, 0, 0);
+        fillParent(console,   0, 0, 0, 0);
+        fillParent(homePage,  0, 0, 0, 0);
+        fillParent(tabFolder, 5, 5, 5, 5);
+        
+        tabFolder.pack();
+        createMenuBar();
+        
+        shellSizeTracker = new ShellSizeTracker("main", shell, preferences);
+        shellSizeTracker.start();
+        
+        try {
+            String       boundsKey = ShellSizeTracker.getBoundsKey(shell, "main");
+            JSONObject   bounds    = preferences.getPreference(boundsKey);
+            
+            if (null != bounds) {
+                Integer x, y, w, h;
+                try {
+                    x = bounds.getInt("x");
+                    y = bounds.getInt("y");
+                    w = bounds.getInt("width");
+                    h = bounds.getInt("height");
+                } catch (JSONException e) {
+                    throw new RuntimeException(e);
+                }
+                
+                if ((null != w) && (null != h)) {
+                    shell.setBounds(x,y,w,h);
+                }
+            }
+            
+            else {
+                shell.setBounds(100, 100, 700, 500);
+            }
+            
+        }
+        catch (IOException e) {
+            Main.warn("exception reading preferences: " + e);
+        }
+        
+    }
+ 
+    //---------------------------------------------------------------
+    private void createMenuBar() {
+//        Menu menu = new Menu(shell, SWT.BAR);
+//        shell.setMenuBar(menu);
+//        MenuItem fileMenuItem = new MenuItem(menu, SWT.CASCADE);
+//        fileMenuItem.setText("File");
+//        MenuItem editMenuItem = new MenuItem(menu, SWT.CASCADE);
+//        editMenuItem.setText("Edit");
+     }        
+
+    //---------------------------------------------------------------
+    private void uiRun() {
+        shell.open();
+        
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+        display.dispose();
+    }
+
+    //---------------------------------------------------------------
+    private CTabItem createTabItem(CTabFolder tabFolder, String text) {
+        CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE);
+        tabItem.setText(text);
+        
+        Font       font     = tabItem.getFont();
+        FontData[] fontData = font.getFontData();
+        
+        for (FontData fontDatum: fontData) {
+            double newHeight = fontDatum.getHeight() * 1.25;
+            fontDatum.setHeight((int) newHeight);
+        }
+        
+        font = new Font(display, fontData);
+        tabItem.setFont(font);
+        
+        return tabItem;
+    }
+    
+    //---------------------------------------------------------------
+    private void fillParent(Control control, int marginT, int marginR, int marginB, int marginL ) {
+        FormLayout formLayout = new FormLayout();
+        
+        formLayout.marginTop    = marginT; 
+        formLayout.marginBottom = marginB;
+        formLayout.marginLeft   = marginL;
+        formLayout.marginRight  = marginR;
+        
+        FormData formData = new FormData();
+        
+        formData.left     = new FormAttachment(0);
+        formData.right    = new FormAttachment(100);
+        formData.top      = new FormAttachment(0);
+        formData.bottom   = new FormAttachment(100);
+
+        control.getParent().setLayout(formLayout);
+        control.setLayoutData(formData);
+    }
+    
+    //---------------------------------------------------------------
+    private String getBrowserURL() {
+        String result;
+        
+        ServerSettings settings = weinre.server.Main.getSettings();
+        
+        String host = settings.getNiceHostName();
+        int    port = settings.getHttpPort();
+        
+        result = "http://" + host + ":" + port + "/";
+        
+        return result;
+    }
+    
+    //---------------------------------------------------------------
     private Font getMonospaceFont(Control control) {
         FontData[] fontData = control.getDisplay().getFontList(null, true);
         
@@ -340,6 +312,7 @@
         return new Font(control.getDisplay(), fontFound);
     }
     
+    //---------------------------------------------------------------
     private FontData findFontNamed(FontData[] fontData, String name) {
         for (FontData fontDatum: fontData) {
             if (fontDatum.getStyle() != SWT.NORMAL) continue;
@@ -349,6 +322,7 @@
         return null;
     }
     
+    //---------------------------------------------------------------
     @SuppressWarnings("unused")
     private void dumpFontData(FontData[] fontData) {
         for (FontData fontDatum: fontData) {
diff --git a/weinre.application/src/weinre/application/GUIPreferences.java b/weinre.application/src/weinre/application/GUIPreferences.java
new file mode 100644
index 0000000..200ea0a
--- /dev/null
+++ b/weinre.application/src/weinre/application/GUIPreferences.java
@@ -0,0 +1,52 @@
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2010, 2011 IBM Corporation
+ */
+
+package weinre.application;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.wink.json4j.JSONException;
+import org.apache.wink.json4j.JSONObject;
+
+import weinre.server.Utility;
+
+
+//-------------------------------------------------------------------
+public class GUIPreferences {
+    static final private String PROPERTIES_FILE_NAME = "ui.properties";
+    
+    private Properties properties;
+    
+    //---------------------------------------------------------------
+    public GUIPreferences() {
+        super();
+
+        properties = Utility.readPropertiesFile(PROPERTIES_FILE_NAME);
+    }
+    
+    //---------------------------------------------------------------
+    public JSONObject getPreference(String key) throws IOException {
+        String val = properties.getProperty(key);
+        if (null == val) return null;
+
+        try {
+            return new JSONObject(val);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    //---------------------------------------------------------------
+    public void setPreference(String key, JSONObject json) {
+        String val = json.toString();
+        
+        properties.setProperty(key, val);
+        Utility.writePropertiesFile(PROPERTIES_FILE_NAME, properties);
+    }
+
+}
diff --git a/weinre.application/src/com/phonegap/weinre/application/ShellSizeTracker.java b/weinre.application/src/weinre/application/ShellSizeTracker.java
similarity index 76%
rename from weinre.application/src/com/phonegap/weinre/application/ShellSizeTracker.java
rename to weinre.application/src/weinre/application/ShellSizeTracker.java
index 20f05cd..5fbad4b 100644
--- a/weinre.application/src/com/phonegap/weinre/application/ShellSizeTracker.java
+++ b/weinre.application/src/weinre/application/ShellSizeTracker.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.application;
+package weinre.application;
 
 import org.apache.wink.json4j.JSONException;
 import org.apache.wink.json4j.JSONObject;
@@ -17,9 +17,7 @@
 import org.eclipse.swt.widgets.Monitor;
 import org.eclipse.swt.widgets.Shell;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class ShellSizeTracker {
 
     private String         name;
@@ -29,11 +27,15 @@
     private Point          lastSize;
     private Point          lastLocation;
     private long           lastChange;
+    private boolean        stop;
 
-    /**
-     * 
-     */
-    static public String getMonitorSetupKey(final Display display) {
+    //---------------------------------------------------------------
+    static public String getBoundsKey(Shell shell, String name) {
+        return "bounds-" + name + "-" + ShellSizeTracker.getMonitorSetupKey(shell.getDisplay());        
+    }
+    
+    //---------------------------------------------------------------
+    static private String getMonitorSetupKey(final Display display) {
         StringBuffer keyBuffer = new StringBuffer();
 
         Monitor[] monitors = display.getMonitors();
@@ -59,9 +61,7 @@
         return keyBuffer.toString();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public ShellSizeTracker(String name, final Shell shell, GUIPreferences preferences) {
         super();
         
@@ -71,19 +71,26 @@
         this.dirty        = false;
         this.lastSize     = new Point(0,0);
         this.lastLocation = new Point(0,0);
+        this.stop         = false;
         
         shell.addControlListener(new ControlListener() {
             public void controlMoved(ControlEvent e)   {shellMoved();}
             public void controlResized(ControlEvent e) {shellMoved();}
         });
         
-        System.out.println("monitor key: " + getMonitorSetupKey(shell.getDisplay()));
-        startWaiterThread();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
+    public void start() {
+        startWaiterThread();
+    }
+    
+    //---------------------------------------------------------------
+    public void stop() {
+        
+    }
+    
+    //---------------------------------------------------------------
     private void shellMoved() {
         dirty        = true;
         lastChange   = System.currentTimeMillis();
@@ -91,9 +98,7 @@
         lastSize     = shell.getSize();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void checkForChanges() {
         if (!dirty) return;
         if (shell.isDisposed()) return;
@@ -111,26 +116,22 @@
         }
         
         String key;
-        String val;
-        key = preferences.getBoundsKey(shell, name);
-        val = valueJSON.toString();
+        key = ShellSizeTracker.getBoundsKey(shell, name);
         
-        preferences.setPreference(key, val);
-        preferences.saveToFile();
-        
+        preferences.setPreference(key, valueJSON);
+
         dirty = false;
     }
 
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private Thread startWaiterThread() {
         Runnable runnable = new Runnable() {
             public void run() {
                 while (true) {
                     try { Thread.sleep(1000); } catch(InterruptedException e) { return; }
                     
+                    if (stop) return;
                     if (shell.isDisposed()) return;
                     
                     shell.getDisplay().asyncExec(new Runnable() {
diff --git a/weinre.application/weinre application using ~weinre-server.settings.launch b/weinre.application/weinre application using ~weinre-server.settings.launch
index def714b..75a0fe3 100644
--- a/weinre.application/weinre application using ~weinre-server.settings.launch
+++ b/weinre.application/weinre application using ~weinre-server.settings.launch
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/weinre.application/src/com/phonegap/weinre/application/GUIMain.java"/>
+<listEntry value="/weinre.application/src/weinre/application/GUIMain.java"/>
 </listAttribute>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
 <listEntry value="1"/>
@@ -10,7 +10,7 @@
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
 <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.phonegap.weinre.application.GUIMain"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="weinre.application.GUIMain"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="weinre.application"/>
 <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread"/>
 </launchConfiguration>
diff --git a/weinre.build/build.properties b/weinre.build/build.properties
index 51f73d2..319717e 100644
--- a/weinre.build/build.properties
+++ b/weinre.build/build.properties
@@ -8,7 +8,7 @@
 #-----------------------------------------------------------
 # weinre version
 #-----------------------------------------------------------
-WEINRE_VERSION: 1.0.0
+WEINRE_VERSION: 1.1.0
 
 #-----------------------------------------------------------
 # some common locations used in the ant scripts
@@ -21,85 +21,6 @@
 VENDOR: vendor
 
 #-----------------------------------------------------------
-# location of pre-built vendor libs
-#-----------------------------------------------------------
-VENDOR_URL: http://cloud.github.com/downloads/pmuellr/weinre-vendor/vendor-1.0.0.zip
-
-#-----------------------------------------------------------
-# location of Apache Commons CLI
-#-----------------------------------------------------------
-
-CLI_VERSION:    1.2
-CLI_URL_PREFIX: http://www.apache.org/dist/commons/cli/
-
-CLI_URL:        ${CLI_URL_PREFIX}/binaries/commons-cli-${CLI_VERSION}-bin.zip
-CLI_BASENAME:   commons-cli-${CLI_VERSION}/commons-cli-${CLI_VERSION}
-
-#-----------------------------------------------------------
-# location of JSON4J 
-#-----------------------------------------------------------
-
-JSON4J_VERSION:    1.1.2-incubating
-JSON4J_URL_PREFIX: http://www.apache.org/dist/incubator/wink
-
-JSON4J_BIN_URL:    ${JSON4J_URL_PREFIX}/${JSON4J_VERSION}/apache-wink-${JSON4J_VERSION}.zip
-JSON4J_SRC_URL:    ${JSON4J_URL_PREFIX}/${JSON4J_VERSION}/apache-wink-${JSON4J_VERSION}-src.zip
-
-#-----------------------------------------------------------
-# location of Eclipse Jetty
-#-----------------------------------------------------------
-
-JETTY_VERSION:              7.1.6.v20100715
-JETTY_URL_PREFIX:           http://repo1.maven.org/maven2/org/eclipse/jetty
-
-JETTY_SRC_JAR_NAME:         jetty-all-server-${JETTY_VERSION}-sources.jar
-JETTY_SRC_URL:              ${JETTY_URL_PREFIX}/aggregate/jetty-all-server/${JETTY_VERSION}/${JETTY_SRC_JAR_NAME}
-
-JETTY_BIN_JAR_NAME:         jetty-all-server-${JETTY_VERSION}.jar
-JETTY_BIN_URL:              ${JETTY_URL_PREFIX}/aggregate/jetty-all-server/${JETTY_VERSION}/${JETTY_BIN_JAR_NAME}
-
-#-----------------------------------------------------------
-# location of servlet API 
-#-----------------------------------------------------------
-
-JAVAX_SERVLET_VERSION:      2.5
-JAVAX_SERVLET_VERSION_IMPL: 6.1H.8
-JAVAX_SERVLET_URL_PREFIX:   http://repo1.maven.org/maven2/org/mortbay/jetty
-
-JAVAX_SERVLET_JAR_NAME:     servlet-api-${JAVAX_SERVLET_VERSION}-${JAVAX_SERVLET_VERSION_IMPL}.jar
-JAVAX_SERVLET_URL:          ${JAVAX_SERVLET_URL_PREFIX}/servlet-api-${JAVAX_SERVLET_VERSION}/${JAVAX_SERVLET_VERSION_IMPL}/${JAVAX_SERVLET_JAR_NAME}
-
-#-----------------------------------------------------------
-# location of Eclipse SWT
-#-----------------------------------------------------------
-
-SWT_VERSION_MAJOR: 3.6
-SWT_VERSION:       ${SWT_VERSION_MAJOR}-201006080911
-SWT_URL_PREFIX:    http://download.eclipse.org/eclipse/downloads/drops/R-${SWT_VERSION}
-
-#-----------------------------------------------------------
-# location of WebKit Web Inspector
-#-----------------------------------------------------------
-
-WEBKIT_VERSION_PREVIOUS: r67358
-WEBKIT_VERSION:          r70098
-WEBKIT_URL_PREFIX:       https://svn.webkit.org/repository/webkit/trunk/
-
-#-----------------------------------------------------------
-# location of scooj
-#-----------------------------------------------------------
-
-SCOOJ_VERSION:    master
-SCOOJ_URL_PREFIX: https://github.com/pmuellr/scooj/raw/${SCOOJ_VERSION}
-
-#-----------------------------------------------------------
-# location of modjewel
-#-----------------------------------------------------------
-
-MODJEWEL_VERSION:    master
-MODJEWEL_URL_PREFIX: https://github.com/pmuellr/modjewel/raw/${MODJEWEL_VERSION}
-
-#-----------------------------------------------------------
 # project names used by the build scripts
 #-----------------------------------------------------------
 
diff --git a/weinre.build/build.xml b/weinre.build/build.xml
index 3d1340f..621925e 100644
--- a/weinre.build/build.xml
+++ b/weinre.build/build.xml
@@ -13,6 +13,7 @@
     
     <property file="personal.properties" />
     <property file="build.properties" />
+    <property file="vendor.properties" />
 
     <!-- hint: override in your personal.properties -->
     <property name="BUILDER" value="The Unknown Builder"/>
@@ -73,8 +74,8 @@
         
         <echo file="${OUT}/build-info.txt" message="${build-info-text}"/>
         
-        <antcall target="compile-java"/>
         <antcall target="build-vendor"/>
+        <antcall target="compile-java"/>
         <antcall target="build-web"/>
         <antcall target="build-doc"/>
         <antcall target="build-json-idl"/>
@@ -153,7 +154,6 @@
         <echo message="compiling scoop modules"/>
         <exec executable="python" failonerror="true" failifexecutionfails="true">
             <arg  file="vendor/scooj/scoopc.py"/>
-            <arg value="--quiet"/>
             <arg value="--out"/>
             <arg  file="${TMP}/modules"/>
             <arg  file="../${PROJECT_WEB}/modules"/>
@@ -188,6 +188,19 @@
             </fileset>
         </copy>
 
+        <echo message="building InjectedScript.js"/>
+        <echo 
+            file    = "${WEB}/weinre/target/InjectedScript.js"
+            message = "var injectedScriptConstructor = ${line.separator}"
+        />
+        <concat 
+            destfile = "${WEB}/weinre/target/InjectedScript.js"
+            append   = "true"
+        >
+            <fileset file="${VENDOR}/webkit/WebCore/inspector/InjectedScriptSource.js"/>
+        </concat>
+            
+        <echo message="building versions.js"/>
         <copy todir="${WEB}">
             <fileset dir="../${PROJECT_WEB}">
                 <include name="versions.js"/>
@@ -208,6 +221,13 @@
                 <filter token="JAVAX_SERVLET_VERSION_IMPL" value="${JAVAX_SERVLET_VERSION_IMPL}"/>
             </filterset>
         </copy>
+
+        <echo message="building add-css-properties.js"/>
+        <exec executable="python" failonerror="true" failifexecutionfails="true">
+            <arg  file="scripts/build-css-properties.py"/>
+            <arg value="vendor/webkit/WebCore/CSSPropertyNames.in"/>
+            <arg value="${WEB}/add-css-properties.js"/>
+        </exec>
         
     </target>
 
@@ -285,6 +305,13 @@
             <arg file="${CACHED}/json-idl"/>
         </exec>
 
+        <exec executable="python" failonerror="true" failifexecutionfails="true">
+            <arg file="scripts/collect-all-json-idl.py"/>
+            <arg value="-min"/>
+            <arg file="${CACHED}/json-idl/all-json-idls-min.js"/>
+            <arg file="${CACHED}/json-idl"/>
+        </exec>
+
     </target>
 
     <!-- ============================================================
@@ -334,7 +361,7 @@
         <jar destfile="${OUT}/weinre.jar">
             <manifest>
                 <attribute name="Built-By" value="${ant.file.basename} - ${ant.project.name}"/>
-                <attribute name="Main-Class" value="com.phonegap.weinre.server.Main"/>
+                <attribute name="Main-Class" value="weinre.server.Main"/>
             </manifest>
             
             <fileset file="${OUT}/build-info.txt"/>
@@ -378,7 +405,7 @@
         <jar destfile="${OUT}/weinre-ui.jar">
             <manifest>
                 <attribute name="Built-By" value="${ant.file.basename} - ${ant.project.name}"/>
-                <attribute name="Main-Class" value="com.phonegap.weinre.application.GUIMain"/>
+                <attribute name="Main-Class" value="weinre.application.GUIMain"/>
             </manifest>
             
             <fileset file="${OUT}/build-info.txt"/>
diff --git a/weinre.build/debug.sh b/weinre.build/debug.sh
new file mode 100755
index 0000000..c63b146
--- /dev/null
+++ b/weinre.build/debug.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+CWD=`dirname $0`
+WEINRE=`dirname $CWD`
+CP=$WEINRE/weinre.server/bin:$WEINRE/weinre.build/out:$WEINRE/weinre.build/vendor/cli/commons-cli.jar:$WEINRE/weinre.build/vendor/jetty/jetty.jar:$WEINRE/weinre.build/vendor/json4j/json4j.jar:$WEINRE/weinre.build/vendor/jetty/servlet-api.jar
+PORT=8096
+DEBUG=jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:$PORT
+
+java \
+	-agentlib:$DEBUG \
+	-Dfile.encoding=UTF-8 \
+	-classpath $CP \
+	weinre.server.Main
\ No newline at end of file
diff --git a/weinre.build/get-vendor.xml b/weinre.build/get-vendor.xml
index 25671ec..04103da 100644
--- a/weinre.build/get-vendor.xml
+++ b/weinre.build/get-vendor.xml
@@ -9,21 +9,169 @@
     
     <property file="personal.properties"/>
     <property file="build.properties"/>
+    <property file="vendor.properties"/>
     
     <!-- ============================================================ -->
 
     <target name="get-vendor">
+        <echo>Go get some coffee, this is going to take a while</echo>
             
+        <delete dir="${TMP}"/>
+        
         <delete dir="${VENDOR}"/>
         <mkdir  dir="${VENDOR}"/>
 
+        <antcall target="get-cli"/>
+        <antcall target="get-json4j"/>
+        <antcall target="get-jetty"/>
+        <antcall target="get-scooj"/>
+        <antcall target="get-modjewel"/>
+        <antcall target="get-web-inspector"/>
+        <antcall target="get-swt-mac"/>
+    </target>
+    
+    <!-- ============================================================ -->
+
+    <target name="get-cli">
+        <delete dir="${VENDOR}/cli"/>
+        <mkdir  dir="${VENDOR}/cli"/>
+        
         <delete dir="${TMP}"/>
         <mkdir  dir="${TMP}"/>
-
-        <get src="${VENDOR_URL}" dest="${TMP}/vendor.zip" verbose="true"/>
-        <unzip src="${TMP}/vendor.zip" dest="."/>
         
+        <get src="${CLI_URL}" dest="${TMP}/commons-cli.zip" verbose="false"/>
+        <unzip src="${TMP}/commons-cli.zip" dest="${TMP}">
+            <patternset>
+                <include name="${CLI_BASENAME}-sources.jar"/>
+                <include name="${CLI_BASENAME}.jar"/>
+            </patternset>
+        </unzip>
+                    
+            
+        <copy file="${TMP}/${CLI_BASENAME}.jar"         tofile="${VENDOR}/cli/commons-cli.jar"/>
+        <copy file="${TMP}/${CLI_BASENAME}-sources.jar" tofile="${VENDOR}/cli/commons-cli-src.jar"/>
+            
         <delete dir="${TMP}"/>
     </target>
     
+    <!-- ============================================================ -->
+
+    <target name="get-json4j">
+        <delete dir="${VENDOR}/json4j"/>
+        <mkdir  dir="${VENDOR}/json4j"/>
+        
+        <delete dir="${TMP}"/>
+        <mkdir  dir="${TMP}"/>
+
+        <get src="${JSON4J_BIN_URL}" dest="${TMP}/json4j.zip" verbose="false"/>
+        <unzip src="${TMP}/json4j.zip" dest="${TMP}">
+            <patternset>
+                <include name="**/wink-json4j-${JSON4J_VERSION}.jar"/>
+            </patternset>
+        </unzip>
+
+        <copy file="${TMP}/apache-wink-${JSON4J_VERSION}/ext/wink-json4j-provider/lib/wink-json4j-${JSON4J_VERSION}.jar" tofile="${VENDOR}/json4j/json4j.jar"/>
+        
+        <delete dir="${TMP}"/>
+        <mkdir  dir="${TMP}"/>
+        <get src="${JSON4J_SRC_URL}" dest="${TMP}/json4j-src.zip" verbose="false"/>
+        <unzip src="${TMP}/json4j-src.zip" dest="${TMP}/src">
+            <patternset>
+                <include name="**/wink-json4j/src/main/java/org/apache/wink/json4j/**/*"/>
+            </patternset>
+        </unzip>
+        
+        <zip destfile="${VENDOR}/json4j/json4j-src.jar" basedir="${TMP}/src"/>
+
+        <delete dir="${TMP}"/>
+    </target>
+    
+    <!-- ============================================================ -->
+
+    <target name="get-jetty">
+        <delete dir="${VENDOR}/jetty"/>
+        <mkdir  dir="${VENDOR}/jetty"/>
+        
+        <get src="${JETTY_SRC_URL}"     dest="${VENDOR}/jetty/jetty-src.jar"   verbose="false"/>
+        <get src="${JETTY_BIN_URL}"     dest="${VENDOR}/jetty/jetty.jar"       verbose="false"/>
+        <get src="${JAVAX_SERVLET_URL}" dest="${VENDOR}/jetty/servlet-api.jar" verbose="false"/>
+    </target>
+    
+    <!-- ============================================================ -->
+
+    <target name="get-scooj">
+        <delete dir="${VENDOR}/scooj"/>
+        <mkdir  dir="${VENDOR}/scooj"/>
+        
+        <get src="${SCOOJ_URL_PREFIX}/scooj.js"  dest="${VENDOR}/scooj/scooj.js"  verbose="false"/>
+        <get src="${SCOOJ_URL_PREFIX}/scoopc.py" dest="${VENDOR}/scooj/scoopc.py" verbose="false"/>
+    </target>
+    
+    <!-- ============================================================ -->
+
+    <target name="get-modjewel">
+        <delete dir="${VENDOR}/modjewel"/>
+        <mkdir  dir="${VENDOR}/modjewel"/>
+        
+        <get src="${MODJEWEL_URL_PREFIX}/modjewel-require.js"  dest="${VENDOR}/modjewel/modjewel-require.js"  verbose="false"/>
+        <get src="${MODJEWEL_URL_PREFIX}/module2transportd.py" dest="${VENDOR}/modjewel/module2transportd.py" verbose="false"/>
+    </target>
+    
+    <!-- ============================================================ -->
+
+    <target name="get-web-inspector">
+        <delete dir="${VENDOR}/webkit"/>
+        <mkdir  dir="${VENDOR}/webkit/WebCore"/>
+        
+        <exec executable="svn" dir="${VENDOR}/WebKit/WebCore">
+            <arg value="export"/>
+            <arg value="-r"/>
+            <arg value="${WEBKIT_VERSION}"/>
+            <arg value="${WEBKIT_URL_PREFIX}/Source/WebCore/inspector"/>
+        </exec>
+        
+        <exec executable="svn" dir="${VENDOR}/WebKit/WebCore">
+            <arg value="export"/>
+            <arg value="-r"/>
+            <arg value="${WEBKIT_VERSION}"/>
+            <arg value="${WEBKIT_URL_PREFIX}/Source/WebCore/English.lproj"/>
+        </exec>
+        
+        <exec executable="svn" dir="${VENDOR}/WebKit/WebCore">
+            <arg value="export"/>
+            <arg value="-r"/>
+            <arg value="${WEBKIT_VERSION}"/>
+            <arg value="${WEBKIT_URL_PREFIX}/Source/WebCore/css/CSSPropertyNames.in"/>
+        </exec>
+        
+        <exec executable="grep" outputproperty="gpl-grep-results" dir="${VENDOR}/WebKit/WebCore">
+            <arg value="-r"/>        
+            <arg value="GPL"/>        
+            <arg value="."/>        
+        </exec>
+        
+        <condition property="found-no-gpl-files">
+            <equals arg1="" arg2="${gpl-grep-results}"/>
+        </condition>
+        
+        <fail unless="found-no-gpl-files" message="The string GPL was found in the WebKit files"/>
+            
+    </target>
+    
+    <target name="get-swt-mac">
+        <delete dir="${VENDOR}/swt"/>
+        <mkdir  dir="${VENDOR}/swt"/>
+            
+        <delete dir="${TMP}"/>
+        <mkdir dir="${TMP}"/>
+            
+        <get src="${SWT_URL_PREFIX}/swt-${SWT_VERSION_MAJOR}-cocoa-macosx-x86_64.zip" dest="${TMP}/swt.zip" verbose="false"/>
+        <unzip src="${TMP}/swt.zip" dest="${TMP}"/>
+            
+        <copy file="${TMP}/src.zip"       tofile="${VENDOR}/swt/cocoa-macosx-x86_64/swt-src.jar"/>
+        <copy file="${TMP}/swt-debug.jar" tofile="${VENDOR}/swt/cocoa-macosx-x86_64/swt.jar"/>
+        
+        <delete dir="${TMP}"/>
+    </target>
+
 </project>
diff --git a/weinre.build/sample.personal.properties b/weinre.build/sample.personal.properties
index cd08d0b..82e22f8 100644
--- a/weinre.build/sample.personal.properties
+++ b/weinre.build/sample.personal.properties
@@ -18,4 +18,17 @@
 
 USE_GROWL:    true
 
-X_USE_JAVAC:    true
+USE_JAVAC:    false
+
+#------------------------------------------------------------------------------
+# the libraries commented out below are particularly slow to get from their
+# originating locations, and are good to cache locally.  The definitions 
+# override those in vendor.properties
+#------------------------------------------------------------------------------
+
+#CACHED_LIBRARIES:          file:///Users/me/Sites/weinre-cached-libraries
+
+#SWT_URL_PREFIX:            ${CACHED_LIBRARIES}
+#JETTY_URL_PREFIX:          ${CACHED_LIBRARIES}/jetty
+#JAVAX_SERVLET_URL_PREFIX:  ${CACHED_LIBRARIES}/jetty
+#JSON4J_URL_PREFIX:         ${CACHED_LIBRARIES}/wink
diff --git a/weinre.build/scripts/build-client-html.py b/weinre.build/scripts/build-client-html.py
index c71d57c..fb32e7d 100644
--- a/weinre.build/scripts/build-client-html.py
+++ b/weinre.build/scripts/build-client-html.py
@@ -14,8 +14,6 @@
 import optparse
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def main():
     if len(sys.argv) < 2:
         error("expecting parameters [web directory]")
@@ -33,8 +31,6 @@
     createIndexFile(iFileName, oFileName, moduleDir)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def createIndexFile(iFileName, oFileName, moduleDir):
     with open(iFileName) as iFile: lines = iFile.readlines()
     
@@ -54,7 +50,6 @@
                 '<meta http-equiv="X-UA-Compatible" content="chrome=1">\n'
                 '<link rel="shortcut icon" href="../images/weinre-icon-64x64.png">\n',
                 '<title>weinre</title>\n',
-                '<link rel="stylesheet" type="text/css" href="weinre/client.css">\n',
                 '<script type="text/javascript" src="weinre/check-for-webkit.js"></script>\n',
                 '<script type="text/javascript" src="weinre/hacks.js"></script>\n',
                 '<script type="text/javascript" src="../modjewel-require.js"></script>\n',
@@ -70,7 +65,8 @@
         elif pattern_head_end.match(line):
             foundEnd = True
             newLines.append("<!-- ========== weinre additions: starting ========== -->\n")
-            newLines.append('<script type="text/javascript" src="../interfaces/all-json-idls.js"></script>\n')
+            newLines.append('<link rel="stylesheet" type="text/css" href="weinre/client.css">\n')
+            newLines.append('<script type="text/javascript" src="../interfaces/all-json-idls-min.js"></script>\n')
             newLines.append('<script type="text/javascript">require("weinre/client/Client").main()</script>\n')
             newLines.append("<!-- ========== weinre additions: done ========== -->\n")
             newLines.append(line)
@@ -86,8 +82,6 @@
     log("created %s" % oFileName)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def getModules(moduleDir):
     modules = []
     
@@ -98,25 +92,18 @@
         modules.append("weinre/client/%s" % module)
 
     return modules
-    
         
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def log(message):
     message = "%s: %s" % (PROGRAM_NAME, message)
     print >>sys.stderr, message
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def error(message):
     log(message)
     sys.exit(-1)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 PROGRAM_NAME = os.path.basename(sys.argv[0])
 
 main()
diff --git a/weinre.build/scripts/build-css-properties.py b/weinre.build/scripts/build-css-properties.py
index f380583..f4e73e5 100644
--- a/weinre.build/scripts/build-css-properties.py
+++ b/weinre.build/scripts/build-css-properties.py
@@ -36,7 +36,7 @@
     properties.sort()
         
     jsonString = json.dumps(properties, indent=4)
-    jsString = "Weinre.addCSSProperties(%s)" % jsonString
+    jsString = 'require("weinre/common/Weinre").addCSSProperties(%s)' % jsonString
 
     oFile = open(oFileName, "w")
     oFile.write(jsString)
@@ -45,22 +45,16 @@
     log("generated css properties in: " + oFileName)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def log(message):
     message = "%s: %s" % (PROGRAM_NAME, message)
     print >>sys.stderr, message
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def error(message):
     log(message)
     sys.exit(-1)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 PROGRAM_NAME = os.path.basename(sys.argv[0])
 
 main()
diff --git a/weinre.build/scripts/build-target-scripts.py b/weinre.build/scripts/build-target-scripts.py
index e887b1c..6738363 100644
--- a/weinre.build/scripts/build-target-scripts.py
+++ b/weinre.build/scripts/build-target-scripts.py
@@ -14,13 +14,9 @@
 import optparse
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def main():
     
     #----------------------------------------------------------------
-    # parse args    
-    #----------------------------------------------------------------
     if len(sys.argv) < 4:
         error("expecting parameters piecesHtmlFile srcDir outputDir")
     
@@ -35,14 +31,10 @@
     if not os.path.isdir(oDirName):     error("output directory not a directory: '" + oDirName + "'")
     
     #----------------------------------------------------------------
-    # read the "pieces" file
-    #----------------------------------------------------------------
     with open(iFileName, "r") as iFile:
         lines = iFile.readlines()
         
     #----------------------------------------------------------------
-    # get the scripts from the pieces file
-    #----------------------------------------------------------------
     scripts     = []
     scriptNames = {}
     scriptSrc   = {}
@@ -55,6 +47,7 @@
         
         baseScriptFile = match.group(1)
         scriptFile = os.path.join(srcDirName, baseScriptFile)
+        if scriptFile == "weinre-demo.js": continue
         if not os.path.exists(scriptFile):   error("script file not found: '" + scriptFile + "'")
         
         scripts.append(scriptFile)
@@ -68,20 +61,14 @@
         # log("read: %s" % scriptFile)
 
     #----------------------------------------------------------------
-    # write the target-script.js file
-    #----------------------------------------------------------------
     oFileName = os.path.join(oDirName, "target-script.js")
     writeMergedFile(oFileName, scripts, scriptNames, scriptSrc)
 
     #----------------------------------------------------------------
-    # write the target-script-min.js file
-    #----------------------------------------------------------------
     oFileName = os.path.join(oDirName, "target-script-min.js")
     writeMergedFile(oFileName, scripts, scriptNames, scriptMin)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def writeMergedFile(oFileName, scripts, scriptNames, srcs):
 
     lines = []
@@ -104,9 +91,6 @@
     
     log("generated: %s" % oFileName)
 
-
-#--------------------------------------------------------------------
-#
 #--------------------------------------------------------------------
 def min(script):
     patternCommentC   = re.compile(r"/\*.*?\*/",     re.MULTILINE + re.DOTALL)
@@ -122,22 +106,16 @@
     return script
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def log(message):
     message = "%s: %s" % (PROGRAM_NAME, message)
     print >>sys.stderr, message
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def error(message):
     log(message)
     sys.exit(-1)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 PROGRAM_NAME = os.path.basename(sys.argv[0])
 
 main()
diff --git a/weinre.build/scripts/closed-issues.py b/weinre.build/scripts/closed-issues.py
new file mode 100755
index 0000000..8eda3ab
--- /dev/null
+++ b/weinre.build/scripts/closed-issues.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import json
+import httplib
+
+if len(sys.argv) < 3:
+    print "expecting parameters <user> <project>"
+    sys.exit()
+    
+user = sys.argv[1]
+proj = sys.argv[2]
+
+url = "/api/v2/json/issues/list/%s/%s/closed" % (user, proj)
+
+conn = httplib.HTTPConnection("github.com")
+conn.request("GET", url)
+resp = conn.getresponse()
+resp = json.loads(resp.read())
+conn.close()
+
+issues = resp["issues"]
+
+issues.sort(lambda x,y: cmp(x["number"], y["number"]))
+
+for issue in issues:
+    number = issue["number"]
+    title  = issue["title"]
+    date   = issue["closed_at"]
+    
+    template = "<li><a href='https://github.com/%s/%s/issues/%d'>issue %d</a> %s - %s"
+    print template % (user, proj, number, number, date, title)
\ No newline at end of file
diff --git a/weinre.build/scripts/collect-all-json-idl.py b/weinre.build/scripts/collect-all-json-idl.py
index 936a057..dc9467b 100644
--- a/weinre.build/scripts/collect-all-json-idl.py
+++ b/weinre.build/scripts/collect-all-json-idl.py
@@ -14,14 +14,19 @@
 import optparse
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def main():
     if len(sys.argv) < 3:
         error("expecting parameters outputFile inputDir")
         
-    oFileName = sys.argv[1]
-    iDirName  = sys.argv[2]
+    min = False
+    if sys.argv[1] == "-min":
+        min = True
+        oFileName = sys.argv[2]
+        iDirName  = sys.argv[3]
+        
+    else:
+        oFileName = sys.argv[1]
+        iDirName  = sys.argv[2]
     
     entries  = os.listdir(iDirName)
     if 0 == len(entries): error("no files found in '" + iDirName + "'")
@@ -40,7 +45,13 @@
         
         result.append(json.loads(contents))
         
-    jsonString = json.dumps(result, indent=4)
+    if min:
+        result = minimize(result)
+        jsonString = json.dumps(result)
+    
+    else:
+        jsonString = json.dumps(result, indent=4)
+        
     jsString = "require('weinre/common/Weinre').addIDLs(%s)" % jsonString
 
     oFile = open(oFileName, "w")
@@ -50,22 +61,39 @@
     log("generated collected json idls in: " + oFileName)
 
 #--------------------------------------------------------------------
-#
+def minimize(idl):
+    for module in idl:
+        for interface in module["interfaces"]:
+            if "extendedAttributes" in interface:
+                del interface["extendedAttributes"]
+            
+            if "methods" in interface:
+                for method in interface["methods"]:
+                    if "returns" in method:
+                        del method["returns"]
+                    if "callbackParameters" in method:
+                        del method["callbackParameters"]
+                    if "extendedAttributes" in method:
+                        del method["extendedAttributes"]
+                        
+                    if "parameters" in method:
+                        for parameter in method["parameters"]:
+                            if "type" in parameter:
+                                del parameter["type"]
+        
+    return idl
+
 #--------------------------------------------------------------------
 def log(message):
     message = "%s: %s" % (PROGRAM_NAME, message)
     print >>sys.stderr, message
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def error(message):
     log(message)
     sys.exit(-1)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 PROGRAM_NAME = os.path.basename(sys.argv[0])
 
 main()
diff --git a/weinre.build/scripts/simple-idl2json.py b/weinre.build/scripts/simple-idl2json.py
index ac54141..b5cf521 100644
--- a/weinre.build/scripts/simple-idl2json.py
+++ b/weinre.build/scripts/simple-idl2json.py
@@ -18,8 +18,6 @@
 # for some info on JSON Schema for interfaces
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def main():
     
     # parse args
@@ -47,10 +45,12 @@
     # convert to JSONable
     module = parseIDL(content)
     
-    if module["name"] == "core":
-        if len(module["interfaces"]) == 1:
-            if module["interfaces"][0]["name"] == "Inspector":
-                splitInspectorInterfaces(module)
+    splitNotifyInterfaces(module)
+    
+#    if module["name"] == "core":
+#        if len(module["interfaces"]) == 1:
+#            if module["interfaces"][0]["name"] == "Inspector":
+#                splitInspectorInterfaces(module)
 
     # convert out parms to callback parms
     convertOutParms(module)
@@ -75,8 +75,6 @@
         log("generated json file '%s'" %oFileName)
 
 #--------------------------------------------------------------------
-# 
-#--------------------------------------------------------------------
 def convertOutParms(module):
     for interface in module["interfaces"]:
         
@@ -94,49 +92,78 @@
                 method["parameters"] = newParameters
 
 #--------------------------------------------------------------------
-#
+def splitNotifyInterfaces(module):
+    newInterfaces = {}
+    
+    for interface in module["interfaces"][:]:
+
+        if "methods" in interface:
+            for method in interface["methods"][:]:
+                if "extendedAttributes" not in method: continue
+                if "notify" not in method["extendedAttributes"]: continue
+                
+                newInterfaceName = interface["name"] + "Notify"
+                newInterface     = newInterfaces.get(newInterfaceName)
+                
+                if not newInterface:
+                    newInterface = {
+                        "name": newInterfaceName,
+                        "methods": []
+                    }
+                    newInterfaces[newInterfaceName] = newInterface
+                    module["interfaces"].append(newInterface)
+
+                for parameter in method["parameters"]:
+                    if "out" not in parameter:
+                        log("%s notify method %s has an unexpected non-out parameter %s" % (interface["name"], method["name"], parameter["name"]))
+                    else:
+                        del parameter["out"]
+
+                newInterface["methods"].append(method)
+                interface["methods"].remove(method)
+
 #--------------------------------------------------------------------
 def splitInspectorInterfaces(module):
-    intfOrig             = module["interfaces"][0]
-    intfWebInspector     = {}
-    intfInspectorBackend = {}
-    backendInterfaces    = {}
+    intfOrig      = module["interfaces"][0]
+    newInterfaces = {}
     
-    intfWebInspector["name"]     = "WebInspector"
-    intfWebInspector["methods"]  = []
-    
-    module["interfaces"] = [intfWebInspector]
+    module["interfaces"] = []
 
     for method in intfOrig["methods"]:
-        if "notify" not in method["extendedAttributes"]:
-            if "handler" not in method["extendedAttributes"]:
-                log("Inspector method %s has neither a 'notify' nor a 'handler' extended attribute" % (method["name"]))
-                continue
-            
-            handlerInterfaceName = "WebInspector" + method["extendedAttributes"]["handler"] + "Handler"
-            if handlerInterfaceName not in backendInterfaces:
-                backendInterfaces[handlerInterfaceName] = {
-                    "name": handlerInterfaceName,
-                    "methods": []
-                }
-            
-                module["interfaces"].append(backendInterfaces[handlerInterfaceName])
-                
-            handlerInterface = backendInterfaces[handlerInterfaceName]
-                
-            handlerInterface["methods"].append(method)
+        if "domain" not in method["extendedAttributes"]:
+            log("Inspector method %s does not have a 'domain' extended attribute" % (method["name"]))
             continue
             
-        for parameter in method["parameters"]:
-            if "out" not in parameter:
-                log("Inspector method %s has an unexpect non-out parameter %s" % (method["name"], parameter["name"]))
-            else:
-                del parameter["out"]
+        intfName = method["extendedAttributes"]["domain"]
         
-        intfWebInspector["methods"].append(method)
+        if "notify" in method["extendedAttributes"]:
+            intfName += "Notify"
 
-#--------------------------------------------------------------------
-#
+            for parameter in method["parameters"]:
+                if "out" not in parameter:
+                    log("Inspector method %s has an unexpected non-out parameter %s" % (method["name"], parameter["name"]))
+                else:
+                    del parameter["out"]
+
+        intf = newInterfaces.get(intfName)
+        if not intf:
+            intf = {
+                "name": intfName,
+                "methods": []
+            }
+            newInterfaces[intfName] = intf
+            module["interfaces"].append(intf)
+            
+        intf["methods"].append(method)
+            
+#        for parameter in method["parameters"]:
+#            if "out" not in parameter:
+#                log("Inspector method %s has an unexpected non-out parameter %s" % (method["name"], parameter["name"]))
+#            else:
+#                del parameter["out"]
+        
+#        intfWebInspector["methods"].append(method)
+
 #--------------------------------------------------------------------
 def validate(module):
     interfaces = {}
@@ -166,8 +193,6 @@
 
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def checkType(location, interfaces, type):
     typeName = type["name"]
     
@@ -180,8 +205,6 @@
     
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def parseIDL(content):
 
     content = clean(content)
@@ -242,8 +265,6 @@
     return module
 
 #--------------------------------------------------------------------
-# parse extended attributes
-#--------------------------------------------------------------------
 def parseExtendedAttributes(object, eaStrings):
     if not eaStrings: return
     if eaStrings == "": return
@@ -266,8 +287,6 @@
         object["extendedAttributes"] = eas
 
 #--------------------------------------------------------------------
-# parse method
-#--------------------------------------------------------------------
 def parseMethod(match):
     method = {}
     
@@ -281,8 +300,6 @@
     return method
 
 #--------------------------------------------------------------------
-# parse attribute
-#--------------------------------------------------------------------
 def parseAttribute(match):
     attribute = {}
     
@@ -295,8 +312,6 @@
     return attribute
 
 #--------------------------------------------------------------------
-# get type information
-#--------------------------------------------------------------------
 def parseMethodParameters(parameterString):
     parameters = []
     
@@ -330,8 +345,6 @@
     return parameters
 
 #--------------------------------------------------------------------
-# parse parameters
-#--------------------------------------------------------------------
 def getType(name, rank):
     name = name.strip()
     rank = PatternWhiteSpace.sub("", rank)
@@ -366,8 +379,6 @@
     return result
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def clean(content):
     content = PatternCommentsPP.sub("", content)
     content = PatternPreprocessor.sub("", content)
@@ -377,22 +388,16 @@
     return content
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def log(message):
     message = "%s: %s" % (PROGRAM_NAME, message)
     print >>sys.stderr, message
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 def error(message):
     log(message)
     sys.exit(-1)
 
 #--------------------------------------------------------------------
-#
-#--------------------------------------------------------------------
 PROGRAM_NAME = os.path.basename(sys.argv[0])
 
 PatternComments          = re.compile(r"/\*.*?\*/")
diff --git a/weinre.build/vendor.properties b/weinre.build/vendor.properties
new file mode 100644
index 0000000..59aba29
--- /dev/null
+++ b/weinre.build/vendor.properties
@@ -0,0 +1,84 @@
+# ---
+# weinre is available under *either* the terms of the modified BSD license *or* the
+# MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+# 
+# Copyright (c) 2011 IBM Corporation
+# ---
+
+#-----------------------------------------------------------
+# location of WebKit Web Inspector
+#-----------------------------------------------------------
+
+#WEBKIT_VERSION:         r67358
+#WEBKIT_VERSION:         r70098
+#WEBKIT_VERSION:         r76802
+#WEBKIT_VERSION:         r77127
+#WEBKIT_VERSION:         r77819
+WEBKIT_VERSION:          r78584
+WEBKIT_URL_PREFIX:       https://svn.webkit.org/repository/webkit/trunk
+
+#-----------------------------------------------------------
+# location of Apache Commons CLI
+#-----------------------------------------------------------
+
+CLI_VERSION:    1.2
+CLI_URL_PREFIX: http://www.apache.org/dist/commons/cli/
+
+CLI_URL:        ${CLI_URL_PREFIX}/binaries/commons-cli-${CLI_VERSION}-bin.zip
+CLI_BASENAME:   commons-cli-${CLI_VERSION}/commons-cli-${CLI_VERSION}
+
+#-----------------------------------------------------------
+# location of JSON4J 
+#-----------------------------------------------------------
+
+JSON4J_VERSION:    1.1.2-incubating
+JSON4J_URL_PREFIX: http://www.apache.org/dist/incubator/wink
+
+JSON4J_BIN_URL:    ${JSON4J_URL_PREFIX}/${JSON4J_VERSION}/apache-wink-${JSON4J_VERSION}.zip
+JSON4J_SRC_URL:    ${JSON4J_URL_PREFIX}/${JSON4J_VERSION}/apache-wink-${JSON4J_VERSION}-src.zip
+
+#-----------------------------------------------------------
+# location of Eclipse Jetty
+#-----------------------------------------------------------
+
+JETTY_VERSION:              7.1.6.v20100715
+JETTY_URL_PREFIX:           http://repo1.maven.org/maven2/org/eclipse/jetty
+
+JETTY_SRC_JAR_NAME:         jetty-all-server-${JETTY_VERSION}-sources.jar
+JETTY_SRC_URL:              ${JETTY_URL_PREFIX}/aggregate/jetty-all-server/${JETTY_VERSION}/${JETTY_SRC_JAR_NAME}
+
+JETTY_BIN_JAR_NAME:         jetty-all-server-${JETTY_VERSION}.jar
+JETTY_BIN_URL:              ${JETTY_URL_PREFIX}/aggregate/jetty-all-server/${JETTY_VERSION}/${JETTY_BIN_JAR_NAME}
+
+#-----------------------------------------------------------
+# location of servlet API 
+#-----------------------------------------------------------
+
+JAVAX_SERVLET_VERSION:      2.5
+JAVAX_SERVLET_VERSION_IMPL: 6.1H.8
+JAVAX_SERVLET_URL_PREFIX:   http://repo1.maven.org/maven2/org/mortbay/jetty
+
+JAVAX_SERVLET_JAR_NAME:     servlet-api-${JAVAX_SERVLET_VERSION}-${JAVAX_SERVLET_VERSION_IMPL}.jar
+JAVAX_SERVLET_URL:          ${JAVAX_SERVLET_URL_PREFIX}/servlet-api-${JAVAX_SERVLET_VERSION}/${JAVAX_SERVLET_VERSION_IMPL}/${JAVAX_SERVLET_JAR_NAME}
+
+#-----------------------------------------------------------
+# location of Eclipse SWT
+#-----------------------------------------------------------
+
+SWT_VERSION_MAJOR: 3.6
+SWT_VERSION:       ${SWT_VERSION_MAJOR}-201006080911
+SWT_URL_PREFIX:    http://download.eclipse.org/eclipse/downloads/drops/R-${SWT_VERSION}
+
+#-----------------------------------------------------------
+# location of scooj
+#-----------------------------------------------------------
+
+SCOOJ_VERSION:    master
+SCOOJ_URL_PREFIX: https://github.com/pmuellr/scooj/raw/${SCOOJ_VERSION}
+
+#-----------------------------------------------------------
+# location of modjewel
+#-----------------------------------------------------------
+
+MODJEWEL_VERSION:    master
+MODJEWEL_URL_PREFIX: https://github.com/pmuellr/modjewel/raw/${MODJEWEL_VERSION}
diff --git a/weinre.doc/Building.body.html b/weinre.doc/Building.body.html
index 26f9bdc..ca19816 100644
--- a/weinre.doc/Building.body.html
+++ b/weinre.doc/Building.body.html
@@ -8,7 +8,11 @@
 <p>The source repository for weinre is maintained at 
 <a href="https://github.com/pmuellr/weinre">GitHub</a>.
 
-<p>To build the current version of <span class="weinre">weinre</span>, you need to be using Eclipse.
+<p>To build the current version of <span class="weinre">weinre</span>, you will 
+probably want to use Eclipse.  If that's not an option, there is some 
+experimental support in the main ant build script to compile the Java code 
+outside of Eclipse.  Explore the <tt>build.xml</tt> file to see how that's
+done.
 
 <p>At development time, <span class="weinre">weinre</span> consists of 5 Eclipse
 projects.  See the file <tt>README.md</tt> in the
diff --git a/weinre.doc/ChangeLog.body.html b/weinre.doc/ChangeLog.body.html
index 1405e7b..037a9f7 100644
--- a/weinre.doc/ChangeLog.body.html
+++ b/weinre.doc/ChangeLog.body.html
@@ -5,6 +5,32 @@
  * Copyright (c) 2011 IBM Corporation
 -->
 
+<h2>2011/03/02 - version 1.1.0</h2>
+<ul>
+<li>added Timeline panel; tracks timers, intervals, XHRs, some other events, and
+    <tt>console.markTimeline(<i>string</i>)</tt>
+<li>now showing matching style rules in Elements panel
+<li>no more diagnostic messages in the user's console; they are now written
+    to the server console
+<li>caught up to a more recent version of Web Inspector
+<li>refactoring, technical debt paydown
+</ul>
+
+<p>issues closed:
+<ul>
+<li><a href='https://github.com/pmuellr/weinre/issues/10'>issue 10</a> enable Timeline panel, and provide some events
+<li><a href='https://github.com/pmuellr/weinre/issues/20'>issue 20</a> catch up to latest Web Inspector code base
+<li><a href='https://github.com/pmuellr/weinre/issues/23'>issue 23</a> mac app's web pages can't connect to server
+<li><a href='https://github.com/pmuellr/weinre/issues/24'>issue 24</a> weinre server runs slowly on windows
+<li><a href='https://github.com/pmuellr/weinre/issues/25'>issue 25</a> pay down technical debt
+<li><a href='https://github.com/pmuellr/weinre/issues/28'>issue 28</a> create a standalone Java launch
+<li><a href='https://github.com/pmuellr/weinre/issues/29'>issue 29</a> autoconnect does not always work
+<li><a href='https://github.com/pmuellr/weinre/issues/30'>issue 30</a> all-json-idls.js is a pig
+<li><a href='https://github.com/pmuellr/weinre/issues/31'>issue 31</a> redirect error/warn/info/debug messages from client and target to server
+<li><a href='https://github.com/pmuellr/weinre/issues/32'>issue 32</a> monospace font too small everywhere
+<li><a href='https://github.com/pmuellr/weinre/issues/33'>issue 33</a> update doc
+</ul>
+
 <h2>2011/01/25 - version 1.0.0</h2>
 <ul>
 <li> Don't display "not implemented" messages. Closes <a href="https://github.com/pmuellr/weinre/issues/1">issue 19</a>.
diff --git a/weinre.doc/Home.body.html b/weinre.doc/Home.body.html
index 20b51bc..1660429 100644
--- a/weinre.doc/Home.body.html
+++ b/weinre.doc/Home.body.html
@@ -7,7 +7,8 @@
 -->
 
 <p><span class="weinre">weinre</span> is <b>We</b>b <b>In</b>spector <b>Re</b>mote.
-Pronounced like the word "winery".
+Pronounced like the word "winery".  Or maybe like the word "weiner".  Who knows,
+really.
 
 <p>It's a debugger for web pages, like 
 FireBug (for FireFox)
@@ -23,6 +24,7 @@
 so if you've used Safari's Web Inspector or Chrome's Developer Tools,  
 <span class="weinre">weinre</span> will be very familiar. 
 
+<!--
 <div class="note">
 <p>NOTE: Please note that <span class="weinre">weinre</span> is still under development and 
 is not fully operational.  
@@ -35,6 +37,7 @@
 </ul>
 
 </div>
+-->
 
 <p>Here's what you can do with it:
 
diff --git a/weinre.doc/License.body.html b/weinre.doc/License.body.html
index d09972d..2884bba 100644
--- a/weinre.doc/License.body.html
+++ b/weinre.doc/License.body.html
@@ -9,21 +9,27 @@
 
 <ul class="spaced"> 
 
-<li>Files from <a href="http://webkit.org/">WebKit build r70098</a>.  
+<li>Files from <a href="http://webkit.org/">WebKit</a>.  
 Web Inspector code.  Although WebKit in general contains both BSD and
 LGPL code, only BSD licensed code is used by weinre.
 
-<li>Files from <a href="http://www.eclipse.org/jetty/">Eclipse Jetty 7.1.6.v20100715</a>.  
+<li>Files from <a href="http://www.eclipse.org/jetty/">Eclipse Jetty</a>.  
 HTTP server.  License: ASLv2 and EPLv1
 
-<li>Files from <a href="https://github.com/pmuellr/scooj">Scooj</a>.  
+<li>Files from <a href="http://www.eclipse.org/swt/">Eclipse SWT</a>.  
+Platform UI toolkit.  License: EPLv1
+
+<li>Files from <a href="https://github.com/pmuellr/scooj">scooj</a>.  
 JavaScript OO wrapper.  License: MIT
 
-<li>Files from <a href="http://commons.apache.org/cli/">Apache Commons CLI 1.2</a>.  
+<li>Files from <a href="https://github.com/pmuellr/modjewel">modjewel</a>.  
+CommonJS runtime for the browser.  License: MIT
+
+<li>Files from <a href="http://commons.apache.org/cli/">Apache Commons CLI</a>.  
 Command-line parser.  License: ASLv2
 
-<li>Files from <a href="http://www.eclipse.org/swt/">Eclipse SWT 3.6</a>.  
-Platform UI toolkit.  License: EPLv1
+<li>Files from <a href="http://incubator.apache.org/wink/">Apache Wink</a>.  
+JSON codecs.  License: ASLv2
 
 </ul>
 
diff --git a/weinre.doc/TestDrive.body.html b/weinre.doc/TestDrive.body.html
index df76763..76991e8 100644
--- a/weinre.doc/TestDrive.body.html
+++ b/weinre.doc/TestDrive.body.html
@@ -10,6 +10,15 @@
 this walk through first, then follow along and run <span class="weinre">weinre</span> yourself
 to make sure it's installed and running correctly.  
 
+<p>You may also want to check out 
+<a href="http://www.youtube.com/watch?v=gaAI29UkVCc">the movie</a>, which
+shows a walk through with the demo page.
+
+<div class="note">
+<p>NOTE: The images below are from a slightly older version of weinre and the
+demo page, but are close enough.
+</div>
+
 <p>After you're done with the
 walk through, if you want to learn how to debug your own web pages with
 <span class="weinre">weinre</span>, 
diff --git a/weinre.doc/boilerplate-header.html.txt b/weinre.doc/boilerplate-header.html.txt
index 383c2e2..32adc4f 100644
--- a/weinre.doc/boilerplate-header.html.txt
+++ b/weinre.doc/boilerplate-header.html.txt
@@ -12,9 +12,25 @@
 <title>weinre - @PAGE_NAME@</title>
 <link rel="stylesheet" href="css/main.css" type="text/css">
 <script src="scripts/main.js"></script>
+<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-736164-7']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>
 </head>
+
 <body>
 
+<a href="https://github.com/pmuellr/weinre"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://assets0.github.com/img/5d21241b64dc708fcbb701f68f72f41e9f1fadd6?repo=&url=http%3A%2F%2Fs3.amazonaws.com%2Fgithub%2Fribbons%2Fforkme_left_red_aa0000.png&path=" alt="Fork me on GitHub"></a>
+
 <!-- ======================================================================= -->
 <h1 class="page-title">weinre - @PAGE_NAME@</h1>
 
diff --git a/weinre.server.android/AndroidManifest.xml b/weinre.server.android/AndroidManifest.xml
index 2578f0c..c8f5931 100644
--- a/weinre.server.android/AndroidManifest.xml
+++ b/weinre.server.android/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.phonegap.weinre.server.android"
+      package="weinre.server.android"
       android:versionCode="1"
       android:versionName="1.0">
     <application android:icon="@drawable/icon" android:label="@string/app_name">
diff --git a/weinre.server.android/src/com/phonegap/weinre/server/android/MainActivity.java b/weinre.server.android/src/weinre/server/android/MainActivity.java
similarity index 90%
rename from weinre.server.android/src/com/phonegap/weinre/server/android/MainActivity.java
rename to weinre.server.android/src/weinre/server/android/MainActivity.java
index 84205c5..26a7fe8 100644
--- a/weinre.server.android/src/com/phonegap/weinre/server/android/MainActivity.java
+++ b/weinre.server.android/src/weinre/server/android/MainActivity.java
@@ -1,11 +1,12 @@
-package com.phonegap.weinre.server.android;
+package weinre.server.android;
 
 import android.app.Activity;
 import android.os.Bundle;
 
-import com.phonegap.weinre.server.Main;
+import weinre.server.Main;
+import weinre.server.android.R;
 
-//-----------------------------------------------------------------------------
+//---------------------------------------------------------------------------------
 public class MainActivity extends Activity {
     
     private Main main;
diff --git a/weinre.server/interfaces/WeinreClientCommands.idl b/weinre.server/interfaces/WeinreClientCommands.idl
index 5c3072b..35d5a74 100644
--- a/weinre.server/interfaces/WeinreClientCommands.idl
+++ b/weinre.server/interfaces/WeinreClientCommands.idl
@@ -5,6 +5,8 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
+// messages from the client to the server
+
 module weinre {
     interface WeinreClientCommands {
     
@@ -15,6 +17,11 @@
         
         void connectTarget(in string clientId, in string targetId);
         void disconnectTarget(in string clientId);
+        
+        void logDebug(   in string message );
+        void logInfo(    in string message );
+        void logWarning( in string message );
+        void logError(   in string message );
     };
 }
 
diff --git a/weinre.server/interfaces/WeinreClientEvents.idl b/weinre.server/interfaces/WeinreClientEvents.idl
index 8707679..4e9f0d9 100644
--- a/weinre.server/interfaces/WeinreClientEvents.idl
+++ b/weinre.server/interfaces/WeinreClientEvents.idl
@@ -5,6 +5,8 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
+// messages from the server to the client
+
 module weinre {
     interface WeinreClientEvents {
     
diff --git a/weinre.server/interfaces/WeinreTargetCommands.idl b/weinre.server/interfaces/WeinreTargetCommands.idl
index b7de6d8..ed3f051 100644
--- a/weinre.server/interfaces/WeinreTargetCommands.idl
+++ b/weinre.server/interfaces/WeinreTargetCommands.idl
@@ -5,6 +5,8 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
+// messages from the target to the server
+
 module weinre {
     interface WeinreTargetCommands {
     
@@ -12,6 +14,10 @@
 
         void sendClientCallback(string callbackId, Object args);
 
+        void logDebug(   in string message );
+        void logInfo(    in string message );
+        void logWarning( in string message );
+        void logError(   in string message );
     };
 }
 
diff --git a/weinre.server/interfaces/WeinreTargetEvents.idl b/weinre.server/interfaces/WeinreTargetEvents.idl
index 7f70c28..36af730 100644
--- a/weinre.server/interfaces/WeinreTargetEvents.idl
+++ b/weinre.server/interfaces/WeinreTargetEvents.idl
@@ -5,6 +5,8 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
+// messages from the server to the target
+
 module weinre {
     interface WeinreTargetEvents {
     
diff --git a/weinre.server/src/com/phonegap/weinre/server/ScriptEventQueue.java b/weinre.server/src/com/phonegap/weinre/server/ScriptEventQueue.java
deleted file mode 100644
index 70c805e..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/ScriptEventQueue.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * 
- */
-public class ScriptEventQueue {
-
-    static public ScriptEventQueue $ = new ScriptEventQueue();
-    
-    private BlockingQueue<String> queue;
-    private AtomicBoolean         closed;
-    
-    /**
-     * 
-     */
-    private ScriptEventQueue() {
-        super();
-        
-        this.queue = new LinkedBlockingQueue<String>();
-        this.closed = new AtomicBoolean(false);
-    }
-
-    /**
-     * 
-     */
-    public void close() {
-        closed.set(true);
-    }
-    
-    /**
-     * 
-     */
-    public boolean isClosed() {
-        return closed.get();
-    }
-
-    /**
-     * 
-     */
-    public void add(String item) {
-        if (isClosed()) return;
-        
-        queue.add(item);
-    }
-    
-    /**
-     * 
-     */
-    public String getNext() {
-        if (isClosed()) return null;
-        
-        String result;
-
-        try {
-            result = queue.poll(5, TimeUnit.SECONDS);
-        }
-        catch (InterruptedException e) {
-            result = null;
-        }
-        
-        return result;
-    }
-    
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/ServerConsoleUpdater.java b/weinre.server/src/com/phonegap/weinre/server/ServerConsoleUpdater.java
deleted file mode 100644
index 41671ce..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/ServerConsoleUpdater.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server;
-
-/**
- * 
- */
-public class ServerConsoleUpdater {
-
-    /**
-     * 
-     */
-    public ServerConsoleUpdater() {
-        super();
-    }
-    
-    /**
-     * 
-     */
-    public boolean addServerConsoleMessage(String message, boolean stdout) {
-        return false;
-    }
-    
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/InspectorBackend.java b/weinre.server/src/com/phonegap/weinre/server/service/InspectorBackend.java
deleted file mode 100644
index c81db37..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/InspectorBackend.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.wink.json4j.JSONArray;
-
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.Connector;
-
-public abstract class InspectorBackend {
-
-    public static String lastActivePanelName;
-    
-    /**
-     * 
-     */
-    public InspectorBackend() {
-        super();
-    }
-
-    /**
-     * 
-     */
-    public String getInterfaceName() {
-        return getClass().getSimpleName();
-    }
-    
-    /**
-     * forwards all requests to connected peers 
-     */
-    public void __doesNotUnderstand(Channel channel, String methodName, JSONArray args) throws IOException {
-        Connector connector = channel.getConnector();
-        if (null == connector) return;
-        
-        List<Connector> connections = connector.getConnections();
-        
-        for (Connector connection: connections) {
-            connection.getChannel().sendEvent(getInterfaceName(), methodName, args.toArray());
-        } 
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspector.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspector.java
deleted file mode 100644
index 0acc718..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspector.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.wink.json4j.JSONArray;
-
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.Connector;
-
-/**
- * 
- */
-public class WebInspector {
-
-    /**
-     * 
-     */
-    public WebInspector() {
-        super();
-    }
-    
-    /**
-     * 
-     */
-    public void __doesNotUnderstand(Channel channel, String methodName, JSONArray args) throws IOException {
-        Connector connector = channel.getConnector();
-        List<Connector> connections = connector.getConnections();
-        
-        for (Connector connection: connections) {
-            connection.getChannel().sendEvent("WebInspector", methodName, args.toArray());
-        }
-    }
-
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorApplicationCacheHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorApplicationCacheHandler.java
deleted file mode 100644
index b49e0d3..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorApplicationCacheHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-
-/**
- * 
- */
-public class WebInspectorApplicationCacheHandler extends InspectorBackend {
-
-    /**
-     * 
-     */
-    public WebInspectorApplicationCacheHandler() {
-        super();
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorBackendHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorBackendHandler.java
deleted file mode 100644
index 8347e40..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorBackendHandler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-import java.io.IOException;
-
-import org.apache.wink.json4j.JSONArray;
-
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.Main;
-
-
-/**
- * 
- */
-public class WebInspectorBackendHandler extends InspectorBackend {
-
-    /**
-     * 
-     */
-    public WebInspectorBackendHandler() {
-        super();
-    }
-
-    /**
-     * 
-     */
-    public void setInjectedScriptSource(Channel channel, String scriptSource, String callbackId) throws IOException {
-        channel.sendCallback("WeinreClientEvents", callbackId);
-    }
-
-    /**
-     * 
-     */
-    public void debug_dispatchOnInjectedScript(Channel channel, Number injectedScriptId, String methodName, String arguments, String callbackId) throws IOException {
-        Main.debug("dispatchOnInjectedScript(" + methodName + ")");
-        
-        JSONArray args = new JSONArray();
-        args.add(injectedScriptId);
-        args.add(methodName);
-        args.add(arguments);
-        args.add(callbackId);
-        __doesNotUnderstand(channel, "dispatchOnInjectedScript", args);
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorControllerHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorControllerHandler.java
deleted file mode 100644
index c426712..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorControllerHandler.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-import java.io.IOException;
-import java.util.Properties;
-
-import org.apache.wink.json4j.JSONException;
-import org.apache.wink.json4j.JSONObject;
-
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.Utility;
-
-
-/**
- * 
- */
-public class WebInspectorControllerHandler extends InspectorBackend {
-
-    static final private String AppKey       = "applicationSettings";
-    static final private String SesKey       = "sessionSettings";
-    static final private String SettingsName = "client-settings.properties";
-    
-    private Properties settings;
-    
-    /**
-     * 
-     */
-    public WebInspectorControllerHandler() {
-        super();
-        
-        readSettings();
-    }
-
-    /**
-     * 
-     */
-    public void getSettings(Channel channel, String callbackId) throws IOException {
-
-        JSONObject settingsResult = new JSONObject();
-        
-        try {
-            settingsResult.put("application", settings.getProperty(AppKey));
-            settingsResult.put("session",     settings.getProperty(SesKey));
-        } catch (JSONException e) {
-            throw new RuntimeException(e);
-        }
-        
-        channel.sendCallback("WeinreClientEvents", callbackId, settings);
-    }
-
-    /**
-     * 
-     */
-    public void saveApplicationSettings(Channel channel, String settingsString, String callbackId) throws IOException {
-        settings.setProperty(AppKey, settingsString);
-        writeSettings();
-        
-        channel.sendCallback("WeinreClientEvents", callbackId, settings);
-    }
-    
-    /**
-     * 
-     */
-    public void saveSessionSettings(Channel channel, String settingsString, String callbackId) throws IOException {
-        settings.setProperty(SesKey, settingsString);
-        writeSettings();
-        
-        channel.sendCallback("WeinreClientEvents", callbackId, settings);
-    }
-
-    /**
-     * 
-     */
-    private void readSettings() {
-        settings = Utility.readPropertiesFile(SettingsName);
-        
-        if (!settings.containsKey(AppKey)) settings.setProperty(AppKey, "{}");
-        if (!settings.containsKey(SesKey)) settings.setProperty(SesKey, "{}");
-    }
-
-    /**
-     * 
-     */
-    private void writeSettings() {
-        Utility.writePropertiesFile(SettingsName, settings);
-    }
-
-    /**
-     * 
-     */
-    public void getInspectorState(Channel channel, String callbackId) throws IOException {
-        JSONObject state = new JSONObject();
-        try {
-            state.put("monitoringXHREnabled", false);
-            state.put("pauseOnExceptionsState", false);
-            state.put("resourceTrackingEnabled", false);
-        } catch (JSONException e) {
-            throw new RuntimeException(e);
-        }
-
-        channel.sendCallback("WeinreClientEvents", callbackId, state);
-    }
-
-    /**
-     * 
-     */
-    public void storeLastActivePanel(Channel channel, String panelName, String callbackId) throws IOException {
-        lastActivePanelName = panelName;
-
-        channel.sendCallback("WeinreClientEvents", callbackId);
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorDOMHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorDOMHandler.java
deleted file mode 100644
index 25d9c9e..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorDOMHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-
-/**
- * 
- */
-public class WebInspectorDOMHandler extends InspectorBackend {
-
-    /**
-     * 
-     */
-    public WebInspectorDOMHandler() {
-        super();
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorDebugHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorDebugHandler.java
deleted file mode 100644
index c21a082..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorDebugHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-
-/**
- * 
- */
-public class WebInspectorDebugHandler extends InspectorBackend {
-
-    /**
-     * 
-     */
-    public WebInspectorDebugHandler() {
-        super();
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorProfilerHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorProfilerHandler.java
deleted file mode 100644
index ffaf436..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorProfilerHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-
-/**
- * 
- */
-public class WebInspectorProfilerHandler extends InspectorBackend {
-
-    /**
-     * 
-     */
-    public WebInspectorProfilerHandler() {
-        super();
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorResourceHandler.java b/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorResourceHandler.java
deleted file mode 100644
index ab0cf5b..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WebInspectorResourceHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-
-/**
- * 
- */
-public class WebInspectorResourceHandler extends InspectorBackend {
-
-    /**
-     * 
-     */
-    public WebInspectorResourceHandler() {
-        super();
-    }
-
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WeinreTargetCommands.java b/weinre.server/src/com/phonegap/weinre/server/service/WeinreTargetCommands.java
deleted file mode 100644
index f2dda25..0000000
--- a/weinre.server/src/com/phonegap/weinre/server/service/WeinreTargetCommands.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-package com.phonegap.weinre.server.service;
-
-import java.io.IOException;
-import java.util.List;
-
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.ChannelManager;
-import com.phonegap.weinre.server.Main;
-import com.phonegap.weinre.server.Target;
-
-/**
- * 
- */
-public class WeinreTargetCommands {
-
-    /**
-     * 
-     */
-    public void registerTarget(Channel channel, String url, String callbackId) throws IOException {
-        Target target = new Target(channel, url);
-        
-        channel.sendCallback("WeinreTargetEvents", callbackId, target.getName());
-    }
-    
-    /**
-     * 
-     */
-    @SuppressWarnings("unchecked")
-    public void sendClientCallback(Channel channel, String clientCallbackId, Object args, String callbackId) throws IOException {
-        Object[] argsArray;
-        if (null == args) 
-            argsArray = new Object[0];
-        else 
-            argsArray = ((List<Object>) args).toArray();
-        
-        // the channel to send the callback to is embedded in the callbackId
-        String callbackConnectorId = getCallbackConnectorId(clientCallbackId);
-        if (null == callbackConnectorId) {
-            Main.warn(getClass().getName() + ".sendClientCallback() sent with invalid callbackId: " + clientCallbackId);
-            return;
-        }
-        
-        channel = ChannelManager.$.getChannel(callbackConnectorId);
-        if (null == channel) {
-            // indication that channel was closed; this message may generate a lot of noise
-            Main.warn(getClass().getName() + ".sendClientCallback() unable to find channel : " + callbackConnectorId);
-            return;
-        }
-
-        channel.sendCallback("WeinreClientEvents", clientCallbackId, argsArray);
-    }
-    
-    /**
-     * 
-     */
-    private String getCallbackConnectorId(String callbackId) {
-        int index = callbackId.indexOf("::");
-        return callbackId.substring(0, index);
-    }
-}
diff --git a/weinre.server/src/com/phonegap/weinre/server/Channel.java b/weinre.server/src/weinre/server/Channel.java
similarity index 70%
rename from weinre.server/src/com/phonegap/weinre/server/Channel.java
rename to weinre.server/src/weinre/server/Channel.java
index ced3edd..86ca840 100644
--- a/weinre.server/src/com/phonegap/weinre/server/Channel.java
+++ b/weinre.server/src/weinre/server/Channel.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -19,9 +19,7 @@
 import org.apache.wink.json4j.JSONException;
 import org.apache.wink.json4j.JSONObject;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class Channel {
     
     private String                pathPrefix;
@@ -35,9 +33,7 @@
     private String                remoteHost;
     private String                remoteAddress;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Channel(String pathPrefix, String name, String remoteHost, String remoteAddress) {
         this.pathPrefix         = pathPrefix;
         this.name               = name;
@@ -51,37 +47,27 @@
         this.lastRead           = System.currentTimeMillis();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Connector getConnector() {
         return connector;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getRemoteHost() {
         return remoteHost;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getRemoteAddress() {
         return remoteAddress;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void _setConnector(Connector connector) {
         this.connector = connector;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void sendCallback(String intfName, String callbackId, Object... args) throws IOException {
         if (callbackId == null) return;
         
@@ -92,9 +78,7 @@
         sendEvent(intfName, "sendCallback", innerArgs.toArray());
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void sendEvent(String intfName, String methodName, Object... args) {
         Main.debug(getName() + ": send " + intfName + "." + methodName + "()");
         
@@ -119,16 +103,11 @@
         this.postResponse(responseString);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Object getService(String name) {
         try {
             return getService_(name);
         }
-        catch (ClassNotFoundException e) {
-            throw new RuntimeException(e);
-        }
         catch (InstantiationException e) {
             throw new RuntimeException(e);
         }
@@ -137,27 +116,29 @@
         }
     }
     
-    /**
-     * @throws IllegalAccessException 
-     * @throws InstantiationException 
-     * 
-     */
+    //---------------------------------------------------------------
     @SuppressWarnings("rawtypes")
-    private Object getService_(String name) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
-        Object result = serviceMap.get(name);
-        if (null != result) return result;
+    private Object getService_(String name) throws InstantiationException, IllegalAccessException {
+        if (serviceMap.containsKey(name)) return serviceMap.get(name);
         
-        String klassName = "com.phonegap.weinre.server.service." + name;
-        Class klass = Class.forName(klassName);
-        if (null == klass) throw new ClassNotFoundException("class not found: " + klassName);
+        String klassName = "weinre.server.service." + name;
+        Class  klass = null;
+        try {
+            klass = Class.forName(klassName);
+        }
+        catch (ClassNotFoundException e) {
+            Main.debug("service class not found: " + klassName);
+            serviceMap.put(name, null);
+            return null;
+        }
         
-        result = klass.newInstance();
+        Object result = klass.newInstance();
+        serviceMap.put(name, result);
+        Main.debug("loaded service class: " + klassName);
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void close() {
         isClosed = true;
         requestQueue.shutdown();
@@ -166,62 +147,46 @@
         ChannelManager.$.deregisterChannel(name);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean isClosed() {
         return isClosed;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getPathPrefix() {
         return pathPrefix;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getName() {
         return name;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public long getLastRead() {
         return lastRead;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void updateLastRead() {
         lastRead = System.currentTimeMillis();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void postRequest(String json) {
         if (isClosed()) return;
         
         requestQueue.add(json);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void postResponse(String json) {
         if (isClosed()) return;
         
         responseQueue.add(json);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<String> getRequests(int timeoutSeconds) throws InterruptedException {
         if (isClosed()) return new LinkedList<String>();
         
@@ -230,9 +195,7 @@
         return result;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<String> getResponses(int timeoutSeconds) throws InterruptedException {
         if (isClosed()) return new LinkedList<String>();
         
@@ -241,9 +204,7 @@
         return result;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String toString() {
         return getClass().getName() + "{" + pathPrefix + ":" + name + "}";
     }
diff --git a/weinre.server/src/com/phonegap/weinre/server/ChannelManager.java b/weinre.server/src/weinre/server/ChannelManager.java
similarity index 76%
rename from weinre.server/src/com/phonegap/weinre/server/ChannelManager.java
rename to weinre.server/src/weinre/server/ChannelManager.java
index 15fdc1b..277be1d 100644
--- a/weinre.server/src/com/phonegap/weinre/server/ChannelManager.java
+++ b/weinre.server/src/weinre/server/ChannelManager.java
@@ -5,16 +5,14 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class ChannelManager {
 
     static final public ChannelManager $ = new ChannelManager();
@@ -22,9 +20,7 @@
     private Map<String, Channel>              channelMap;
     private List<ChannelManagerEventListener> eventListeners;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private ChannelManager() {
         super();
         
@@ -32,50 +28,36 @@
         eventListeners = new ArrayList<ChannelManagerEventListener>();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void addEventListener(ChannelManagerEventListener listener) {
         eventListeners.add(listener);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void removeEventListener(ChannelManagerEventListener listener) {
         eventListeners.add(listener);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void fireRegisteredEvent(Channel channel) {
         for (ChannelManagerEventListener listener: eventListeners) {
             listener.channelRegistered(channel);
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void fireDeregisteredEvent(Channel channel) {
         for (ChannelManagerEventListener listener: eventListeners) {
             listener.channelDeregistered(channel);
         }
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Channel getChannel(String channelName) {
         return channelMap.get(channelName);
     }
     
-    /**
-     * This version of getChannel() double-checks that the remoteAddress
-     * this request came from matches the original remoteAddress the
-     * channel was created with.
-     */
+    //---------------------------------------------------------------
     public Channel getChannel(String channelName, String remoteAddress) {
         Channel channel = getChannel(channelName);
         if (null == channel) return null;
@@ -85,16 +67,12 @@
         return channel;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<Channel> getChannels() {
         return new ArrayList<Channel>(channelMap.values());
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Channel registerChannel(String pathPrefix, String channelName, String remoteHost, String remoteAddress) {
         if (channelMap.containsKey(channelName)) return null;
         
@@ -106,9 +84,7 @@
         return channel;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Channel deregisterChannel(String channelName) {
         Channel channel = getChannel(channelName);
         if (null == channel) return null;
diff --git a/weinre.server/src/com/phonegap/weinre/server/ChannelManagerEventListener.java b/weinre.server/src/weinre/server/ChannelManagerEventListener.java
similarity index 62%
rename from weinre.server/src/com/phonegap/weinre/server/ChannelManagerEventListener.java
rename to weinre.server/src/weinre/server/ChannelManagerEventListener.java
index a278092..e97ef7c 100644
--- a/weinre.server/src/com/phonegap/weinre/server/ChannelManagerEventListener.java
+++ b/weinre.server/src/weinre/server/ChannelManagerEventListener.java
@@ -5,20 +5,14 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public interface ChannelManagerEventListener {
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void channelRegistered(Channel channel);
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void channelDeregistered(Channel channel);
 }
diff --git a/weinre.server/src/com/phonegap/weinre/server/Client.java b/weinre.server/src/weinre/server/Client.java
similarity index 75%
rename from weinre.server/src/com/phonegap/weinre/server/Client.java
rename to weinre.server/src/weinre/server/Client.java
index a335b5b..e14bfaf 100644
--- a/weinre.server/src/com/phonegap/weinre/server/Client.java
+++ b/weinre.server/src/weinre/server/Client.java
@@ -5,44 +5,34 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import org.apache.wink.json4j.JSONArray;
 import org.apache.wink.json4j.JSONException;
 import org.apache.wink.json4j.JSONObject;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class Client extends Connector {
 
     private Target connectedTarget;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Client(Channel channel) {
         super(channel);
         _register();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean isClient() {
         return true;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Target getConnectedTarget() {
         return connectedTarget;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void _connect(Target target) {
         if (null == target) return;
         
@@ -56,9 +46,7 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void _disconnect(Target target) {
         if (null == target) return;
         
@@ -72,9 +60,7 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public JSONObject getDescription() {
       JSONObject result = new JSONObject();
       
diff --git a/weinre.server/src/com/phonegap/weinre/server/ConnectionManager.java b/weinre.server/src/weinre/server/ConnectionManager.java
similarity index 78%
rename from weinre.server/src/com/phonegap/weinre/server/ConnectionManager.java
rename to weinre.server/src/weinre/server/ConnectionManager.java
index df61fa8..0d27e2f 100644
--- a/weinre.server/src/com/phonegap/weinre/server/ConnectionManager.java
+++ b/weinre.server/src/weinre/server/ConnectionManager.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -13,9 +13,7 @@
 import java.util.List;
 import java.util.Map;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class ConnectionManager {
 
     static final public ConnectionManager $ = new ConnectionManager();
@@ -24,9 +22,7 @@
     private Map<String,Target> targetMap;
     private boolean            listening = false; 
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private ConnectionManager() {
         super();
         
@@ -34,9 +30,7 @@
         targetMap = Collections.synchronizedMap(new HashMap<String,Target>());
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void startChannelListener() {
         if (listening) return;
         listening = true;
@@ -58,55 +52,41 @@
         });
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void addClient(Client client) {
         clientMap.put(client.getName(), client);
         _sendAllClientsEvent("WeinreClientEvents", "clientRegistered", client.getDescription());
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void addTarget(Target target) {
         targetMap.put(target.getName(), target);
         _sendAllClientsEvent("WeinreClientEvents", "targetRegistered", target.getDescription());
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void _removeClient(Client client) {
         _sendAllClientsEvent("WeinreClientEvents", "clientUnregistered", client.getName());
         clientMap.remove(client.getName());
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void _removeTarget(Target target) {
         _sendAllClientsEvent("WeinreClientEvents", "targetUnregistered", target.getName());
         targetMap.remove(target.getName());
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Client getClient(String id) {
         return clientMap.get(id);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Target getTarget(String id) {
         return targetMap.get(id);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<Client> getClients() {
         List<Client> result = new ArrayList<Client>();
         
@@ -115,9 +95,7 @@
         return result;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<Target> getTargets() {
         List<Target> result = new ArrayList<Target>();
         
@@ -126,9 +104,7 @@
         return result;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void connect(Client client, Target target) {
         if ((client == null) || (target == null)) return;
 
@@ -143,9 +119,7 @@
         _sendConnectionCreatedEvent(client, target);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void disconnect(Client client, Target target) {
         if ((client == null) || (target == null)) return;
 
@@ -155,23 +129,17 @@
         _sendConnectionDestroyedEvent(client, target);
     }
 
-    /*
-     * 
-     */
+    //---------------------------------------------------------------
     private void _sendConnectionCreatedEvent(Client client, Target target) {
         _sendConnectionEvent(client, target, "connectionCreated");
     }
     
-    /*
-     * 
-     */
+    //---------------------------------------------------------------
     private void _sendConnectionDestroyedEvent(Client client, Target target) {
         _sendConnectionEvent(client, target, "connectionDestroyed");
     }
     
-    /*
-     * 
-     */
+    //---------------------------------------------------------------
     private void _sendConnectionEvent(Client client, Target target, String message) {
         String clientName = client.getChannel().getName();
         String targetName = target.getChannel().getName();
@@ -180,18 +148,14 @@
         target.getChannel().sendEvent("WeinreTargetEvents", message, clientName, targetName);
     }
     
-    /*
-     * 
-     */
+    //---------------------------------------------------------------
     private void _sendAllClientsEvent(String intfName, String message, Object... args) {
         for (Client aClient: getClients()) {
             aClient.getChannel().sendEvent(intfName, message, args);
         }
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void closeConnector(Connector connector) {
         if (null == connector) return;
         
@@ -199,9 +163,7 @@
         if (connector.isTarget()) _closeTarget((Target)connector);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void _closeClient(Client client) {
         if (null == client) return;
 
@@ -213,9 +175,7 @@
         _removeClient(client);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void _closeTarget(Target target) {
         if (null == target) return;
 
diff --git a/weinre.server/src/com/phonegap/weinre/server/Connector.java b/weinre.server/src/weinre/server/Connector.java
similarity index 71%
rename from weinre.server/src/com/phonegap/weinre/server/Connector.java
rename to weinre.server/src/weinre/server/Connector.java
index 7b1ea8b..b428ca0 100644
--- a/weinre.server/src/com/phonegap/weinre/server/Connector.java
+++ b/weinre.server/src/weinre/server/Connector.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -14,18 +14,14 @@
 
 import org.apache.wink.json4j.JSONObject;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 abstract public class Connector {
 
     static final protected Lock Lock = new ReentrantLock();
     
     private Channel channel;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Connector(Channel channel) {
         super();
         
@@ -33,31 +29,23 @@
         channel._setConnector(this);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void _register() {
         if (isClient()) ConnectionManager.$.addClient((Client) this);
         if (isTarget()) ConnectionManager.$.addTarget((Target) this);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Channel getChannel() {
         return channel;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getName() {
         return channel.getName();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<Connector> getConnections() {
         List<Connector> result = new ArrayList<Connector>();
         
@@ -79,35 +67,25 @@
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     abstract public JSONObject getDescription();
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean isClosed() {
         return channel.isClosed();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean isClient() {
         return false;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean isTarget() {
         return false;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String toString() {
         return getClass().getName() + "{" + channel + "}";
     }
diff --git a/weinre.server/src/com/phonegap/weinre/server/ConsoleOutputStream.java b/weinre.server/src/weinre/server/ConsoleOutputStream.java
similarity index 80%
rename from weinre.server/src/com/phonegap/weinre/server/ConsoleOutputStream.java
rename to weinre.server/src/weinre/server/ConsoleOutputStream.java
index 13639d7..dc62c2d 100644
--- a/weinre.server/src/com/phonegap/weinre/server/ConsoleOutputStream.java
+++ b/weinre.server/src/weinre/server/ConsoleOutputStream.java
@@ -5,15 +5,13 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class ConsoleOutputStream extends OutputStream {
 
     private Main                 main;
@@ -21,16 +19,12 @@
     private StringBuffer         stringBuffer;
     private boolean              stdout;
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public PrintStream newPrintStream(Main main, PrintStream originalStream, boolean stdout) {
         return new PrintStream(new ConsoleOutputStream(main, originalStream, stdout));
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public ConsoleOutputStream(Main main, PrintStream originalStream, boolean stdout) {
         this.main           = main;
         this.originalStream = originalStream;
@@ -38,6 +32,7 @@
         this.stringBuffer   = new StringBuffer();
     }
     
+    //---------------------------------------------------------------
     @Override
     public void write(int c) throws IOException {
         if (c == 0x0D) return;
@@ -52,9 +47,7 @@
         _writeLine(line);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void _writeLine(String line) {
         originalStream.println(line);
         
diff --git a/weinre.server/src/com/phonegap/weinre/server/Main.java b/weinre.server/src/weinre/server/Main.java
similarity index 75%
rename from weinre.server/src/com/phonegap/weinre/server/Main.java
rename to weinre.server/src/weinre/server/Main.java
index 6cf4e76..1d8ae96 100644
--- a/weinre.server/src/com/phonegap/weinre/server/Main.java
+++ b/weinre.server/src/weinre/server/Main.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.io.PrintStream;
 
@@ -14,12 +14,9 @@
 import org.eclipse.jetty.util.log.Logger;
 import org.eclipse.jetty.util.log.StdErrLog;
 
-import com.phonegap.weinre.server.http.HttpServer;
+import weinre.server.http.HttpServer;
 
-
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class Main {
     
     private static ServerSettings  Settings;
@@ -29,32 +26,30 @@
     private PrintStream  consoleStdout;
     private PrintStream  consoleStderr;
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public void main(String[] args) throws Throwable {
         Main main = new Main(args);
         
         main.run();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public ServerSettings getSettings() {
         return Settings;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
+    static public boolean isDebug() {
+        return Settings.getVerbose();
+    }
+
+    //---------------------------------------------------------------
     static public void warn(  String message ) { Logger.warn(message);  }
     static public void info(  String message ) { Logger.info(message);  }
     static public void debug( String message ) { Logger.debug(message); }
+    static public void error( String message ) { Logger.warn(message);  }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Main(String[] args) {
         super();
         
@@ -68,18 +63,14 @@
         System.setErr(consoleStderr);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void run() throws Throwable, Exception {
         httpServerStart();
         httpServerWaitTillDone();
         exit();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public int exit() {
         if (null != server) {
             try {
@@ -102,9 +93,7 @@
         return 0;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void httpServerStart() {
         // get the default logger - this should be the first thing to touch the log
         Logger defaultLog = Log.getLog();
@@ -130,9 +119,7 @@
         MessageHandler.start();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void httpServerWaitTillDone() {
         try {
             server.join();
@@ -142,21 +129,15 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void serverStarted() {
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void addServerConsoleMessage(String line, boolean stdout) {
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public int severeError(String message) {
         Logger.warn(message);
         Logger.warn("exiting...");
diff --git a/weinre.server/src/com/phonegap/weinre/server/MessageHandler.java b/weinre.server/src/weinre/server/MessageHandler.java
similarity index 78%
rename from weinre.server/src/com/phonegap/weinre/server/MessageHandler.java
rename to weinre.server/src/weinre/server/MessageHandler.java
index 2c49d68..29942b2 100644
--- a/weinre.server/src/com/phonegap/weinre/server/MessageHandler.java
+++ b/weinre.server/src/weinre/server/MessageHandler.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -16,14 +16,10 @@
 import org.apache.wink.json4j.JSONException;
 import org.apache.wink.json4j.JSONObject;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class MessageHandler {
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public void start() {
         final MessageHandler messageHandler = new MessageHandler();
         
@@ -45,15 +41,11 @@
         thread.start();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private MessageHandler() {
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void handleMessages() throws InterruptedException {
         List<Channel> channels = ChannelManager.$.getChannels();
         
@@ -116,15 +108,17 @@
         }
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private void serviceMethodInvoker(Channel channel, String intfName, String methodName, JSONArray argsJSON) {
         Object service;
+
         String methodSignature = intfName + "." + methodName + "()";
 
-        Main.debug(channel.getName() + ": recv " + methodSignature);
+        if (Main.isDebug()) {
+            String methodSignatureParms = intfName + "." + methodName + "(" + argsJSON.toString() + ")";
+            Main.debug(channel.getName() + ": recv " + methodSignatureParms);
+        }
         
         try {
             service = channel.getService(intfName);
@@ -134,6 +128,11 @@
             return;
         }
         
+        if (null == service) {
+            redirectToConnections(channel, intfName, methodName, argsJSON);
+            return;
+        }
+        
         Class serviceClass = service.getClass();
         
         List<Object> args = new ArrayList<Object>(argsJSON);
@@ -145,6 +144,7 @@
                 Main.warn("invalid number of parameters specified for : " + methodSignature);
                 return;
             }
+            
             args.add(0, channel);
             
             try {
@@ -167,41 +167,21 @@
             
             return;
         }
-        
-        Method dnuMethod;
-        try {
-            dnuMethod = serviceClass.getMethod("__doesNotUnderstand", Channel.class, String.class, JSONArray.class);
-        } 
-        catch (SecurityException e) {
-            Main.warn("security exception looking up method __doesNotUnderstand invoking : " + methodSignature + "; " + e);
-            return;
-        } 
-        catch (NoSuchMethodException e) {
-            Main.warn("no __doesNotUnderstand method found while invoking : " + methodSignature + "; " + e);
-            return;
-        }
-        
-        Object[] dnuArgs = new Object[3];
-        dnuArgs[0] = channel;
-        dnuArgs[1] = methodName;
-        try {
-            dnuArgs[2] = new JSONArray(args);
-        } catch (JSONException e1) {
-            throw new RuntimeException(e1);
-        }
-        
-        try {
-            dnuMethod.invoke(service, dnuArgs);
-        } 
-        catch (IllegalArgumentException e) {
-            Main.warn("illegal argument exception invoking __doesNotUnderstand invoking: " + methodSignature + "; " + e);
-        } 
-        catch (IllegalAccessException e) {
-            Main.warn("illegal access exception invoking __doesNotUnderstand invoking: " + methodSignature + "; " + e);
-        } 
-        catch (InvocationTargetException e) {
-            Main.warn("invocation target exception invoking __doesNotUnderstand invoking: " + methodSignature + "; " + e);
-        }
+
+        Main.warn("no method found to invoke for: " + methodSignature);
     }
+
+    //---------------------------------------------------------------
+    private void redirectToConnections(Channel channel, String interfaceName, String methodName, JSONArray args) {
+        Connector connector = channel.getConnector();
+        if (null == connector) return;
+        
+        List<Connector> connections = connector.getConnections();
+        
+        for (Connector connection: connections) {
+            connection.getChannel().sendEvent(interfaceName, methodName, args.toArray());
+        } 
+    }
+
     
 }
diff --git a/weinre.server/src/com/phonegap/weinre/server/MessageQueue.java b/weinre.server/src/weinre/server/MessageQueue.java
similarity index 86%
rename from weinre.server/src/com/phonegap/weinre/server/MessageQueue.java
rename to weinre.server/src/weinre/server/MessageQueue.java
index 0780992..09937ea 100644
--- a/weinre.server/src/com/phonegap/weinre/server/MessageQueue.java
+++ b/weinre.server/src/weinre/server/MessageQueue.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.util.LinkedList;
 import java.util.List;
@@ -27,9 +27,7 @@
     private boolean          closed;
     private Object           closeLock;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public MessageQueue() {
         super();
         
@@ -38,9 +36,7 @@
         closeLock = new Object();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void shutdown() {
         synchronized(closeLock) {
             if (closed) return;
@@ -50,9 +46,7 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void add(E item) {
         synchronized(closeLock) {
             if (closed) throw new IllegalStateException("the blocking queue is closed");
@@ -61,9 +55,7 @@
         queue.add(item);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<E> getAll(int timeout, TimeUnit timeUnit) throws InterruptedException {
         synchronized(closeLock) {
             if (closed) throw new IllegalStateException("the blocking queue is closed");
@@ -91,9 +83,7 @@
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String toString()  {
         return getClass().getName() + "{" + queue.size() + "}";
     }
diff --git a/weinre.server/src/com/phonegap/weinre/server/ServerSettings.java b/weinre.server/src/weinre/server/ServerSettings.java
similarity index 85%
rename from weinre.server/src/com/phonegap/weinre/server/ServerSettings.java
rename to weinre.server/src/weinre/server/ServerSettings.java
index e8ecde0..b7a63b5 100644
--- a/weinre.server/src/com/phonegap/weinre/server/ServerSettings.java
+++ b/weinre.server/src/weinre/server/ServerSettings.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.net.InetAddress;
 import java.net.NetworkInterface;
@@ -25,9 +25,7 @@
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class ServerSettings {
 
     final static private String BoundHostAllConstant = "-all-";
@@ -41,26 +39,20 @@
     private int         deathTimeoutSeconds;
     private Properties  fileProperties;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public ServerSettings getOptions(String[] commandLine) {
         ServerSettings settings = new ServerSettings();
         return settings.parse(commandLine);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private ServerSettings() {
         super();
         
         fileProperties = fromPropertiesFile();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private Options getOptions() {
         Options options = new Options();
        
@@ -77,9 +69,7 @@
         return options;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Map<String,Object> asProperties() {
         Map<String,Object> result = new HashMap<String,Object>();
 
@@ -95,9 +85,7 @@
         return result;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private Properties fromPropertiesFile() {
         Properties result = Utility.readPropertiesFile("server.properties");
         
@@ -110,10 +98,7 @@
         return result;
     }
 
-    
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private ServerSettings parse(String[] commandLineArgs) {
         Options options = getOptions();
 
@@ -150,9 +135,7 @@
         return this;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private int getIntFromOption(CommandLine commandLine, String name, int defaultValue, int min, int max) {
         int result = defaultValue;
         
@@ -178,9 +161,7 @@
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private String getStringFromOption(CommandLine commandLine, String name, String defaultValue) {
         String stringValue = commandLine.getOptionValue(name);
         if (null == stringValue) {
@@ -192,9 +173,7 @@
         return stringValue;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private boolean getBooleanFromOption(CommandLine commandLine, String name, boolean defaultValue) {
         boolean result = defaultValue;
         
@@ -210,37 +189,27 @@
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void error(String message) {
         System.out.println("error with command-line option: " + message);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void printHelp(Options options) {
         new HelpFormatter().printHelp("java -jar weinre.jar [options]", options);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public int getHttpPort() {
         return httpPort;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getBoundHost() {
         return boundHost;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String[] getBoundHosts() {
         if (getBoundHostValue() != null) {
             return new String[] { getBoundHost() };
@@ -266,62 +235,46 @@
         return hosts.toArray(new String[]{});
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getBoundHostValue() {
         if (BoundHostAllConstant.equals(boundHost)) return null;
         
         return boundHost;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean getVerbose() {
         return verbose;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public int getReadTimeoutSeconds() {
         return readTimeoutSeconds;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public int getDeathTimeoutSeconds() {
         return deathTimeoutSeconds;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean useProxy() {
         return false; // useProxy;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean reuseAddr() {
         return reuseAddr;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getNiceHostName() {
         String hostName = getBoundHostValue();
         if (null == hostName) return "localhost";
         return hostName;
     }
         
-    /**
-     *
-     */
+    //---------------------------------------------------------------
     @SuppressWarnings("unused")
     private String getSuperNiceHostName() {
         String hostName = getBoundHost();
diff --git a/weinre.server/src/com/phonegap/weinre/server/Target.java b/weinre.server/src/weinre/server/Target.java
similarity index 79%
rename from weinre.server/src/com/phonegap/weinre/server/Target.java
rename to weinre.server/src/weinre/server/Target.java
index 261e60d..54920ff 100644
--- a/weinre.server/src/com/phonegap/weinre/server/Target.java
+++ b/weinre.server/src/weinre/server/Target.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.util.ArrayList;
 import java.util.LinkedList;
@@ -15,17 +15,13 @@
 import org.apache.wink.json4j.JSONException;
 import org.apache.wink.json4j.JSONObject;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class Target extends Connector {
 
     private List<Client> connectedClients;
     private String       url;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Target(Channel channel, String url) {
         super(channel);
         
@@ -35,23 +31,17 @@
 
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public String getURL() {
         return this.url;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public boolean isTarget() {
         return true;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public List<Client> getConnectedClients() {
         List<Client> result = new LinkedList<Client>();
         
@@ -66,9 +56,7 @@
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void _connect(Client client) {
         if (null == client) return;
         
@@ -84,9 +72,7 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     protected void _disconnect(Client client) {
         if (null == client) return;
         
@@ -102,9 +88,7 @@
         }
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public JSONObject getDescription() {
         JSONObject result = new JSONObject();
         
@@ -120,5 +104,4 @@
         return result;
     }
     
-    
 }
diff --git a/weinre.server/src/com/phonegap/weinre/server/Utility.java b/weinre.server/src/weinre/server/Utility.java
similarity index 87%
rename from weinre.server/src/com/phonegap/weinre/server/Utility.java
rename to weinre.server/src/weinre/server/Utility.java
index 0ce6f38..260cc2b 100644
--- a/weinre.server/src/com/phonegap/weinre/server/Utility.java
+++ b/weinre.server/src/weinre/server/Utility.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.io.File;
 import java.io.FileReader;
@@ -14,21 +14,15 @@
 import java.security.SecureRandom;
 import java.util.Properties;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class Utility {
     
     static private int SequenceNumber = 1 + new SecureRandom().nextInt(Integer.MAX_VALUE - 1);
 
-    /**
-     * class may not be instantiated
-     */
+    //---------------------------------------------------------------
     private Utility() {}
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public synchronized int getNextSequenceNumber() {
         int result = SequenceNumber;
         
@@ -37,9 +31,7 @@
         return result;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public String reverse(String string) {
         char[] responseChars = string.toCharArray();
         
@@ -51,9 +43,7 @@
         return String.valueOf(responseChars);
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public byte[] reverse(byte[] data, int offset, int length) {
         byte[] response = new byte[length];
         
@@ -64,9 +54,7 @@
         return response;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public Properties readPropertiesFile(String fileName) {
         Properties result = new Properties();
         
@@ -101,9 +89,7 @@
         return result;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public void writePropertiesFile(String fileName, Properties properties) {
         String userHome = System.getProperty("user.home");
         if (null == userHome) {
diff --git a/weinre.server/src/com/phonegap/weinre/server/WatchDog.java b/weinre.server/src/weinre/server/WatchDog.java
similarity index 77%
rename from weinre.server/src/com/phonegap/weinre/server/WatchDog.java
rename to weinre.server/src/weinre/server/WatchDog.java
index e9cabe2..9aa6553 100644
--- a/weinre.server/src/com/phonegap/weinre/server/WatchDog.java
+++ b/weinre.server/src/weinre/server/WatchDog.java
@@ -5,20 +5,16 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server;
+package weinre.server;
 
 import java.util.List;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class WatchDog {
 
     public static long ChannelLivelinessTimeout = 5000;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     static public void start() {
 
         final WatchDog watchDog = new WatchDog();
@@ -32,16 +28,12 @@
         thread.start();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private WatchDog() {
         super();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void run() {
         while(true) {
             sleep();
@@ -50,9 +42,7 @@
         }
     }
 
-    /**
-     * Note that this is the only place channels are closed, and eventually, connectors also.
-     */
+    //---------------------------------------------------------------
     private void checkForDeadChannels() {
         List<Channel> channels = ChannelManager.$.getChannels();
         
@@ -68,9 +58,7 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void sleep() {
         try {
             Thread.sleep(1000);
diff --git a/weinre.server/src/com/phonegap/weinre/server/http/ClassPathResourceHandler.java b/weinre.server/src/weinre/server/http/ClassPathResourceHandler.java
similarity index 83%
rename from weinre.server/src/com/phonegap/weinre/server/http/ClassPathResourceHandler.java
rename to weinre.server/src/weinre/server/http/ClassPathResourceHandler.java
index 9568895..13b0072 100644
--- a/weinre.server/src/com/phonegap/weinre/server/http/ClassPathResourceHandler.java
+++ b/weinre.server/src/weinre/server/http/ClassPathResourceHandler.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.http;
+package weinre.server.http;
 
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -14,25 +14,19 @@
 import org.eclipse.jetty.server.handler.ResourceHandler;
 import org.eclipse.jetty.util.resource.Resource;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class ClassPathResourceHandler extends ResourceHandler {
 
     private String pathPrefix;
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public ClassPathResourceHandler(String pathPrefix) {
         super();
         
         this.pathPrefix = pathPrefix;
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public Resource getResource(String path) throws MalformedURLException {
         if ((path == null) || !path.startsWith("/")) {
             throw new MalformedURLException(path);
diff --git a/weinre.server/src/com/phonegap/weinre/server/http/DebugHandler.java b/weinre.server/src/weinre/server/http/DebugHandler.java
similarity index 90%
rename from weinre.server/src/com/phonegap/weinre/server/http/DebugHandler.java
rename to weinre.server/src/weinre/server/http/DebugHandler.java
index db5ba25..13e3f77 100644
--- a/weinre.server/src/com/phonegap/weinre/server/http/DebugHandler.java
+++ b/weinre.server/src/weinre/server/http/DebugHandler.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.http;
+package weinre.server.http;
 
 import java.io.IOException;
 import java.io.PrintStream;
@@ -29,9 +29,7 @@
 */
 public class DebugHandler extends HandlerWrapper {
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void handle(String target, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException {
         try {
             getHandler().handle(target, request, servletRequest, servletResponse);
@@ -45,9 +43,7 @@
         dump(System.out, target, request, response);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void dump(PrintStream oStream, String target, Request request, Response response) {
         oStream.println("----------------------------------------------------------");
         oStream.println("target: " + target);
@@ -60,9 +56,7 @@
         oStream.println("   status: " + response.getStatus());
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     @SuppressWarnings("rawtypes")
     private void dumpHeaders(PrintStream oStream, Request request) {
         Enumeration e = request.getHeaderNames();
diff --git a/weinre.server/src/com/phonegap/weinre/server/http/FilteredRequestLogHandler.java b/weinre.server/src/weinre/server/http/FilteredRequestLogHandler.java
similarity index 84%
rename from weinre.server/src/com/phonegap/weinre/server/http/FilteredRequestLogHandler.java
rename to weinre.server/src/weinre/server/http/FilteredRequestLogHandler.java
index 0902d8d..3a4fad1 100644
--- a/weinre.server/src/com/phonegap/weinre/server/http/FilteredRequestLogHandler.java
+++ b/weinre.server/src/weinre/server/http/FilteredRequestLogHandler.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.http;
+package weinre.server.http;
 
 import java.io.IOException;
 
@@ -16,14 +16,10 @@
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.RequestLogHandler;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class FilteredRequestLogHandler extends RequestLogHandler {
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     @Override
     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
         int status = baseRequest.getResponse().getStatus();
diff --git a/weinre.server/src/com/phonegap/weinre/server/http/HttpServer.java b/weinre.server/src/weinre/server/http/HttpServer.java
similarity index 89%
rename from weinre.server/src/com/phonegap/weinre/server/http/HttpServer.java
rename to weinre.server/src/weinre/server/http/HttpServer.java
index 772f196..bfc07f4 100644
--- a/weinre.server/src/com/phonegap/weinre/server/http/HttpServer.java
+++ b/weinre.server/src/weinre/server/http/HttpServer.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.http;
+package weinre.server.http;
 
 import java.io.IOException;
 
@@ -18,14 +18,16 @@
 import org.eclipse.jetty.server.nio.SelectChannelConnector;
 import org.eclipse.jetty.util.component.LifeCycle;
 
-import com.phonegap.weinre.server.Main;
-import com.phonegap.weinre.server.ServerSettings;
+import weinre.server.Main;
+import weinre.server.ServerSettings;
 
+//-------------------------------------------------------------------
 public class HttpServer {
 
     private Main           main;
     private ServerSettings settings;
     
+    //---------------------------------------------------------------
     public HttpServer(Main main, ServerSettings settings) {
         super();
         
@@ -33,6 +35,7 @@
         this.settings = settings;
     }
     
+    //---------------------------------------------------------------
     public Server run() throws Exception {
         String hostName     = settings.getBoundHostValue();
         String niceHostName = settings.getNiceHostName();
@@ -47,11 +50,8 @@
         Server server = new Server();
         server.setConnectors(new Connector[] { connector });
         server.addLifeCycleListener(new LifeCycle.Listener() {
-            public void lifeCycleStarting(LifeCycle event) {
-                main.serverStarted();
-            }
-
-            public void lifeCycleStarted(LifeCycle event) {}
+            public void lifeCycleStarting(LifeCycle event) {}
+            public void lifeCycleStarted(LifeCycle event) { main.serverStarted(); }
             public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
             public void lifeCycleStopping(LifeCycle event) {}
             public void lifeCycleStopped(LifeCycle event) {}
diff --git a/weinre.server/src/com/phonegap/weinre/server/http/HttpSocketHandler.java b/weinre.server/src/weinre/server/http/HttpSocketHandler.java
similarity index 88%
rename from weinre.server/src/com/phonegap/weinre/server/http/HttpSocketHandler.java
rename to weinre.server/src/weinre/server/http/HttpSocketHandler.java
index e2d0290..df8a0e5 100644
--- a/weinre.server/src/com/phonegap/weinre/server/http/HttpSocketHandler.java
+++ b/weinre.server/src/weinre/server/http/HttpSocketHandler.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.http;
+package weinre.server.http;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -23,21 +23,17 @@
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.AbstractHandler;
 
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.ChannelManager;
-import com.phonegap.weinre.server.Main;
-import com.phonegap.weinre.server.Utility;
+import weinre.server.Channel;
+import weinre.server.ChannelManager;
+import weinre.server.Main;
+import weinre.server.Utility;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class HttpSocketHandler extends AbstractHandler {
     private String pathPrefix; 
     private int    pathPrefixParts;
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public HttpSocketHandler(String pathPrefix) {
         super();
         
@@ -45,9 +41,7 @@
         this.pathPrefixParts = pathPrefix.split("/").length;
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     @Override
     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
         // ! * pathPrefix*
@@ -120,18 +114,14 @@
         response.sendError(405);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void setCORSHeaders(HttpServletResponse response) {
         response.setHeader("Access-Control-Allow-Origin", "*");
         response.setHeader("Access-Control-Max-Age", "600");
         response.setHeader("Access-Control-Allow-Methods", "GET, POST");
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void setCacheHeaders(HttpServletResponse response) {
         response.setHeader("Pragma",        "no-cache");
         response.setHeader("Expires",       "0");
@@ -139,17 +129,13 @@
         response.setHeader("Cache-Control", "no-store");
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void handleOptions(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
         response.setStatus(200);
         response.setContentType("text/plain");
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void handleCreate(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
         String channelName = "" + Utility.getNextSequenceNumber();
         
@@ -163,9 +149,7 @@
         oStream.close();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void handleGet(String channelName, String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
         Channel channel = ChannelManager.$.getChannel(channelName, request.getRemoteAddr());
         if (null == channel) {
@@ -192,9 +176,7 @@
         oStream.close();
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private void printJSONList(ServletOutputStream oStream, List<String> json) throws IOException {
         try {
             oStream.print(new JSONArray(json).toString());
@@ -204,9 +186,7 @@
         }
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void handlePost(String channelName, String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
         Channel channel = ChannelManager.$.getChannel(channelName, request.getRemoteAddr());
         if (null == channel) {
@@ -238,9 +218,7 @@
         response.getOutputStream().close();
     }
     
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     private String readRequestBody(InputStream is) throws IOException {
         StringBuffer stringBuffer = new StringBuffer();
         Reader       reader       = new InputStreamReader(is, "UTF-8");
diff --git a/weinre.server/src/com/phonegap/weinre/server/http/ProxyServer.java b/weinre.server/src/weinre/server/http/ProxyServer.java
similarity index 89%
rename from weinre.server/src/com/phonegap/weinre/server/http/ProxyServer.java
rename to weinre.server/src/weinre/server/http/ProxyServer.java
index 295a454..e290bd7 100644
--- a/weinre.server/src/com/phonegap/weinre/server/http/ProxyServer.java
+++ b/weinre.server/src/weinre/server/http/ProxyServer.java
@@ -5,7 +5,7 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.http;
+package weinre.server.http;
 
 import java.io.IOException;
 
@@ -19,18 +19,21 @@
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jetty.servlets.ProxyServlet;
 
-import com.phonegap.weinre.server.Main;
-import com.phonegap.weinre.server.ServerSettings;
+import weinre.server.Main;
+import weinre.server.ServerSettings;
 
+//-------------------------------------------------------------------
 public class ProxyServer {
     private ServerSettings settings;
     
+    //---------------------------------------------------------------
     public ProxyServer(ServerSettings settings) {
         super();
         
         this.settings = settings;
     }
     
+    //---------------------------------------------------------------
     public void run() throws Exception {
         SelectChannelConnector connector = new SelectChannelConnector();
 
diff --git a/weinre.server/src/com/phonegap/weinre/server/service/WeinreClientCommands.java b/weinre.server/src/weinre/server/service/WeinreClientCommands.java
similarity index 60%
rename from weinre.server/src/com/phonegap/weinre/server/service/WeinreClientCommands.java
rename to weinre.server/src/weinre/server/service/WeinreClientCommands.java
index e94c261..1c58cc2 100644
--- a/weinre.server/src/com/phonegap/weinre/server/service/WeinreClientCommands.java
+++ b/weinre.server/src/weinre/server/service/WeinreClientCommands.java
@@ -5,27 +5,23 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-package com.phonegap.weinre.server.service;
+package weinre.server.service;
 
 import java.io.IOException;
 import java.util.List;
 
 import org.apache.wink.json4j.JSONArray;
 
-import com.phonegap.weinre.server.Channel;
-import com.phonegap.weinre.server.Client;
-import com.phonegap.weinre.server.ConnectionManager;
-import com.phonegap.weinre.server.Main;
-import com.phonegap.weinre.server.Target;
+import weinre.server.Channel;
+import weinre.server.Client;
+import weinre.server.ConnectionManager;
+import weinre.server.Main;
+import weinre.server.Target;
 
-/**
- * 
- */
+//-------------------------------------------------------------------
 public class WeinreClientCommands {
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void registerClient(Channel channel, String callbackId) throws IOException {
         Client client = new Client(channel);
         
@@ -33,9 +29,7 @@
         channel.sendEvent("WeinreClientEvents", "serverProperties", Main.getSettings().asProperties());
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void getTargets(Channel channel, String callbackId) throws IOException {
         List<Target> targets = ConnectionManager.$.getTargets();
         JSONArray targetResults = new JSONArray();
@@ -47,9 +41,7 @@
         channel.sendCallback("WeinreClientEvents", callbackId, targetResults);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void getClients(Channel channel, String callbackId) throws IOException {
         List<Client> clients = ConnectionManager.$.getClients();
         JSONArray clientResults = new JSONArray();
@@ -61,9 +53,7 @@
         channel.sendCallback("WeinreClientEvents", callbackId, clientResults);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void connectTarget(Channel channel, String clientId, String targetId, String callbackId) {
         Client client = ConnectionManager.$.getClient(clientId);
         if (client == null) return;
@@ -74,9 +64,7 @@
         ConnectionManager.$.connect(client, target);
     }
 
-    /**
-     * 
-     */
+    //---------------------------------------------------------------
     public void disconnectTarget(Channel channel, String clientId, String callbackId) {
         Client client = ConnectionManager.$.getClient(clientId);
         if (client == null) return;
@@ -87,4 +75,24 @@
         ConnectionManager.$.disconnect(client, target);
     }
     
+    //---------------------------------------------------------------
+    public void logDebug(Channel channel, String message, String callbackId) {
+        Main.debug("client " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    public void logInfo(Channel channel, String message, String callbackId) {
+        Main.info("client " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    public void logWarning(Channel channel, String message, String callbackId) {
+        Main.warn("client " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    public void logError(Channel channel, String message, String callbackId) {
+        Main.error("client " + channel.getName() + ": " + message);
+    }
+
 }
diff --git a/weinre.server/src/weinre/server/service/WeinreTargetCommands.java b/weinre.server/src/weinre/server/service/WeinreTargetCommands.java
new file mode 100644
index 0000000..bd6d3ee
--- /dev/null
+++ b/weinre.server/src/weinre/server/service/WeinreTargetCommands.java
@@ -0,0 +1,80 @@
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2010, 2011 IBM Corporation
+ */
+
+package weinre.server.service;
+
+import java.io.IOException;
+import java.util.List;
+
+import weinre.server.Channel;
+import weinre.server.ChannelManager;
+import weinre.server.Main;
+import weinre.server.Target;
+
+//-------------------------------------------------------------------
+public class WeinreTargetCommands {
+
+    //---------------------------------------------------------------
+    public void registerTarget(Channel channel, String url, String callbackId) throws IOException {
+        Target target = new Target(channel, url);
+        
+        channel.sendCallback("WeinreTargetEvents", callbackId, target.getName());
+    }
+    
+    //---------------------------------------------------------------
+    @SuppressWarnings("unchecked")
+    public void sendClientCallback(Channel channel, String clientCallbackId, Object args, String callbackId) throws IOException {
+        Object[] argsArray;
+        if (null == args) 
+            argsArray = new Object[0];
+        else 
+            argsArray = ((List<Object>) args).toArray();
+        
+        // the channel to send the callback to is embedded in the callbackId
+        String callbackConnectorId = getCallbackConnectorId(clientCallbackId);
+        if (null == callbackConnectorId) {
+            Main.warn(getClass().getName() + ".sendClientCallback() sent with invalid callbackId: " + clientCallbackId);
+            return;
+        }
+        
+        channel = ChannelManager.$.getChannel(callbackConnectorId);
+        if (null == channel) {
+            // indication that channel was closed; this message may generate a lot of noise
+            Main.warn(getClass().getName() + ".sendClientCallback() unable to find channel : " + callbackConnectorId);
+            return;
+        }
+
+        channel.sendCallback("WeinreClientEvents", clientCallbackId, argsArray);
+    }
+    
+    //---------------------------------------------------------------
+    public void logDebug(Channel channel, String message, String callbackId) {
+        Main.debug("target " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    public void logInfo(Channel channel, String message, String callbackId) {
+        Main.info("target " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    public void logWarning(Channel channel, String message, String callbackId) {
+        Main.warn("target " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    public void logError(Channel channel, String message, String callbackId) {
+        Main.error("target " + channel.getName() + ": " + message);
+    }
+
+    //---------------------------------------------------------------
+    private String getCallbackConnectorId(String callbackId) {
+        int index = callbackId.indexOf("::");
+        return callbackId.substring(0, index);
+    }
+    
+}
diff --git a/weinre.server/weinre server - remote debug.launch b/weinre.server/weinre server - remote debug.launch
new file mode 100644
index 0000000..e88ac8a
--- /dev/null
+++ b/weinre.server/weinre server - remote debug.launch
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/weinre.server"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
+<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;sourceLookupDirector&gt;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;weinre.build&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;weinre.doc&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;weinre.server&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=weinre.server/\/weinre.build\/vendor\/cli\/commons-cli.jar&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=weinre.server/\/weinre.build\/vendor\/jetty\/jetty.jar&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=weinre.server/\/weinre.build\/vendor\/json4j\/json4j.jar&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;packageFragmentRoot handle=&amp;quot;=weinre.server/\/weinre.build\/vendor\/jetty\/servlet-api.jar&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.packageFragmentRoot&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;weinre.server.android&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;javaProject name=&amp;quot;weinre.web&amp;quot;/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#10;&amp;lt;default/&amp;gt;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#10;&lt;/sourceContainers&gt;&#10;&lt;/sourceLookupDirector&gt;&#10;"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
+<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
+<mapEntry key="hostname" value="localhost"/>
+<mapEntry key="port" value="8096"/>
+</mapAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="weinre.server"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
+</launchConfiguration>
diff --git a/weinre.server/weinre server using ~weinre-server.settings.launch b/weinre.server/weinre server using ~weinre-server.settings.launch
index 2e29a1f..4b2d2ab 100644
--- a/weinre.server/weinre server using ~weinre-server.settings.launch
+++ b/weinre.server/weinre server using ~weinre-server.settings.launch
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/weinre.server/src/com/phonegap/weinre/server/Main.java"/>
+<listEntry value="/weinre.server/src/weinre/server/Main.java"/>
 </listAttribute>
 <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
 <listEntry value="1"/>
@@ -10,6 +10,6 @@
 <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
 <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
 </listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.phonegap.weinre.server.Main"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="weinre.server.Main"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="weinre.server"/>
 </launchConfiguration>
diff --git a/weinre.web/client/InspectorBackendStub.js b/weinre.web/client/InspectorBackendStub.js
index 56c912d..8b6532a 100644
--- a/weinre.web/client/InspectorBackendStub.js
+++ b/weinre.web/client/InspectorBackendStub.js
@@ -5,7 +5,6 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-
 (function() {
     var InspectorBackendImpl = require("weinre/client/InspectorBackendImpl")
     window.InspectorBackend = new InspectorBackendImpl()
diff --git a/weinre.web/client/weinre/client.css b/weinre.web/client/weinre/client.css
index 4aae174..0eccff5 100644
--- a/weinre.web/client/weinre/client.css
+++ b/weinre.web/client/weinre/client.css
@@ -9,6 +9,16 @@
     background-image: url(../../images/weinre-icon-32x32.png);
 }
 
+.monospace {
+     font-size:   12px !important;
+     font-family: Monaco, Consolas, Lucida Console, dejavu sans mono, monospace;
+}
+
+.source-code {
+     font-size:   12px !important;
+     font-family: Monaco, Consolas, Lucida Console, dejavu sans mono, monospace;
+}
+
 .weinre-connector-item {
     font-size: 140%;
 }
@@ -40,36 +50,20 @@
     font-size: 200%
 }
 
-.weinreConsole {
-    margin-left: 2em;
-}
-
 .weinreServerProperties {
     margin-left: 2em;
 }
 
-.console_stdout {
-    color: #000;
-}
-
-.console_stderr {
-    color: #F00;
-}
-
 .weinre-normal-text-size {
     font-size: 140%;
 }
 
-body.platform-weinre .monospace, body.platform-weinre .source-code {
-     font-size:   12px;
-     font-family: Monaco, Consolas, Lucida Console, dejavu sans mono, monospace;
-}
-
-.fadeable {
+.weinre-fadeable {
   opacity: 1;
   -webkit-transition: opacity 5s linear;
 }
 
-.fade {
+.weinre-fade {
   opacity: 0;
 }
+
diff --git a/weinre.web/demo/weinre-demo-min.html b/weinre.web/demo/weinre-demo-min.html
index 74db41a..978b170 100644
--- a/weinre.web/demo/weinre-demo-min.html
+++ b/weinre.web/demo/weinre-demo-min.html
@@ -7,31 +7,27 @@
 
 <html>
 <head>
-<title>testing</title>
+<meta name="viewport" content="user-scalable=no, width=device-width, height=device-height">
+<title>weinre demo</title>
+<link rel="stylesheet" href="weinre-demo.css">
 <script src="/target/target-script-min.js"></script>
 
-<style>
-h1 {
-    color: green;
-}
+<script type="text/javascript">
+    require("weinre/common/Weinre").showNotImplemented()
+    require("weinre/target/Target").main()
+</script>
 
-.blue {
-    color: blue;
-}
-
-#metrics {
-    margin:   1em;
-    border:   0.2em solid;
-    padding:  3em;
-}
-</style>
+<script src="weinre-demo.js"></script>
 </head>
 
-<body>
-<h1>this is a green h1 element</h1>
-<h1 class="blue">this is a blue h1 element</h1>
-<h1 style="color:red">this is a red h1 element</h1>
+<body onload="onLoad()">
+<input id="button" type="button" value="start stuff">
+
+<h1>this is a green h1</h1>
+<h1 class="blue">this is a blue h1</h1>
+<h1 style="color:red">this is a red h1</h1>
 <p>Some text, <i>some italic text</i>, and <b>some bold text</b>.
+
 <div id="metrics">a div</div>
 </body>
 
diff --git a/weinre.web/demo/weinre-demo-pieces.html b/weinre.web/demo/weinre-demo-pieces.html
index 1a9bda5..e88f0c5 100644
--- a/weinre.web/demo/weinre-demo-pieces.html
+++ b/weinre.web/demo/weinre-demo-pieces.html
@@ -7,61 +7,58 @@
 
 <html>
 <head>
-<title>testing</title>
-<script src="/client/InjectedScript.js"                                            ></script>
-<script src="/modjewel-require.js"                                                 ></script>
+<meta name="viewport" content="user-scalable=no, width=device-width, height=device-height">
+<title>weinre demo</title>
+<link rel="stylesheet" href="weinre-demo.css">
+<script src="/modjewel-require.js"></script>
 <script type="text/javascript">require("modjewel").warnOnRecursiveRequire(true)</script>
-<script src="/scooj.transportd.js"                                                 ></script>
-<script src="/weinre/common/Weinre.transportd.js"                                  ></script>
-<script src="/weinre/common/IDLTools.transportd.js"                                ></script>
-<script src="/weinre/common/Socket.transportd.js"                                  ></script>
-<script src="/weinre/common/WebSocketXhr.transportd.js"                            ></script>
-<script src="/weinre/common/Binding.transportd.js"                                 ></script>
-<script src="/weinre/common/Callback.transportd.js"                                ></script>
-<script src="/weinre/common/EventListeners.transportd.js"                          ></script>
-<script src="/weinre/target/Console.transportd.js"                                 ></script>
-<script src="/weinre/target/WebInspectorApplicationCacheHandlerImpl.transportd.js" ></script>
-<script src="/weinre/target/WebInspectorBackendHandlerImpl.transportd.js"          ></script>
-<script src="/weinre/target/WebInspectorControllerHandlerImpl.transportd.js"       ></script>
-<script src="/weinre/target/WebInspectorDOMHandlerImpl.transportd.js"              ></script>
-<script src="/weinre/target/WebInspectorDebugHandlerImpl.transportd.js"            ></script>
-<script src="/weinre/target/WebInspectorProfilerHandlerImpl.transportd.js"         ></script>
-<script src="/weinre/target/WebInspectorResourceHandlerImpl.transportd.js"         ></script>
-<script src="/weinre/target/WeinreTargetEventsImpl.transportd.js"                  ></script>
-<script src="/weinre/target/NodeStore.transportd.js"                               ></script>
-<script src="/weinre/target/CSSStore.transportd.js"                                ></script>
-<script src="/weinre/target/InjectedScriptHostImpl.transportd.js"                  ></script>
-<script src="/weinre/target/Target.transportd.js"                                  ></script>
-<script src="/weinre/target/ElementHighlighter.transportd.js"                                  ></script>
-<script src="/interfaces/all-json-idls.js"                                         ></script>
+<script src="/scooj.transportd.js"></script>
+<script src="/weinre/common/Ex.transportd.js"></script>
+<script src="/weinre/common/StackTrace.transportd.js"></script>
+<script src="/weinre/common/Weinre.transportd.js"></script>
+<script src="/weinre/common/IDLTools.transportd.js"></script>
+<script src="/weinre/common/MessageDispatcher.transportd.js"></script>
+<script src="/weinre/common/WebSocketXhr.transportd.js"></script>
+<script src="/weinre/common/Binding.transportd.js"></script>
+<script src="/weinre/common/Callback.transportd.js"></script>
+<script src="/weinre/common/EventListeners.transportd.js"></script>
+<script src="/weinre/common/Native.transportd.js"></script>
+<script src="/weinre/common/IDGenerator.transportd.js"></script>
+<script src="/weinre/target/Console.transportd.js"></script>
+<script src="/add-css-properties.js"></script>
+<script src="/weinre/target/WiConsoleImpl.transportd.js"></script>
+<script src="/weinre/target/WiCSSImpl.transportd.js"></script>
+<script src="/weinre/target/WiDatabaseImpl.transportd.js"></script>
+<script src="/weinre/target/WiDOMImpl.transportd.js"></script>
+<script src="/weinre/target/WiDOMStorageImpl.transportd.js"></script>
+<script src="/weinre/target/WiInspectorImpl.transportd.js"></script>
+<script src="/weinre/target/WiRuntimeImpl.transportd.js"></script>
+<script src="/weinre/target/WeinreTargetEventsImpl.transportd.js"></script>
+<script src="/weinre/target/NodeStore.transportd.js"></script>
+<script src="/weinre/target/CSSStore.transportd.js"></script>
+<script src="/weinre/target/InjectedScriptHostImpl.transportd.js"></script>
+<script src="/weinre/target/Target.transportd.js"></script>
+<script src="/weinre/target/ElementHighlighter.transportd.js"></script>
+<script src="/weinre/target/InjectedScript.js"></script>
+<script src="/weinre/target/Timeline.transportd.js"></script>
+<script src="/interfaces/all-json-idls-min.js"></script>
 
 <script type="text/javascript">
     require("weinre/common/Weinre").showNotImplemented()
     require("weinre/target/Target").main()
 </script>
 
-<style>
-h1 {
-    color: green;
-}
-
-.blue {
-    color: blue;
-}
-
-#metrics {
-    margin:   1em;
-    border:   0.2em solid;
-    padding:  3em;
-}
-</style>
+<script src="weinre-demo.js"></script>
 </head>
 
-<body>
-<h1>this is a green h1 element</h1>
-<h1 class="blue">this is a blue h1 element</h1>
-<h1 style="color:red">this is a red h1 element</h1>
+<body onload="onLoad()">
+<input id="button" type="button" value="start stuff">
+
+<h1>this is a green h1</h1>
+<h1 class="blue">this is a blue h1</h1>
+<h1 style="color:red">this is a red h1</h1>
 <p>Some text, <i>some italic text</i>, and <b>some bold text</b>.
+
 <div id="metrics">a div</div>
 </body>
 
diff --git a/weinre.web/demo/weinre-demo.css b/weinre.web/demo/weinre-demo.css
new file mode 100644
index 0000000..f4715b2
--- /dev/null
+++ b/weinre.web/demo/weinre-demo.css
@@ -0,0 +1,24 @@
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+h1 {
+    color: green;
+}
+
+.blue {
+    color: blue;
+}
+
+#metrics {
+    margin:   1em;
+    border:   0.2em solid;
+    padding:  3em;
+}
+
+#button {
+    font-size: 150%;
+}
\ No newline at end of file
diff --git a/weinre.web/demo/weinre-demo.html b/weinre.web/demo/weinre-demo.html
index 04463ab..150c9cb 100644
--- a/weinre.web/demo/weinre-demo.html
+++ b/weinre.web/demo/weinre-demo.html
@@ -7,30 +7,25 @@
 
 <html>
 <head>
-<title>testing</title>
+<meta name="viewport" content="user-scalable=no, width=device-width, height=device-height">
+<title>weinre demo</title>
+<link rel="stylesheet" href="weinre-demo.css">
 <script src="/target/target-script.js"></script>
 
-<style>
-h1 {
-    color: green;
-}
+<script type="text/javascript">
+    require("weinre/common/Weinre").showNotImplemented()
+    require("weinre/target/Target").main()
+</script>
 
-.blue {
-    color: blue;
-}
-
-#metrics {
-    margin:   1em;
-    border:   0.2em solid;
-    padding:  3em;
-}
-</style>
+<script src="weinre-demo.js"></script>
 </head>
 
-<body>
-<h1>this is a green h1 element</h1>
-<h1 class="blue">this is a blue h1 element</h1>
-<h1 style="color:red">this is a red h1 element</h1>
+<body onload="onLoad()">
+<input id="button" type="button" value="start stuff">
+
+<h1>this is a green h1</h1>
+<h1 class="blue">this is a blue h1</h1>
+<h1 style="color:red">this is a red h1</h1>
 <p>Some text, <i>some italic text</i>, and <b>some bold text</b>.
 
 <div id="metrics">a div</div>
diff --git a/weinre.web/demo/weinre-demo.js b/weinre.web/demo/weinre-demo.js
new file mode 100644
index 0000000..ddec2b9
--- /dev/null
+++ b/weinre.web/demo/weinre-demo.js
@@ -0,0 +1,64 @@
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+//------------------------------------------------------------------------------
+var started = false
+var button
+
+//------------------------------------------------------------------------------
+function onLoad() {
+    if (!button) button = document.getElementById("button")
+    
+    button.addEventListener("click", function() {
+        if (!started) {
+            button.value = "stop stuff"
+            startStuff()
+        }
+        else {
+            button.value = "start stuff"
+            stopStuff()      
+        }
+        started = !started
+    })
+}
+
+//------------------------------------------------------------------------------
+var interval
+
+function startStuff() {
+    interval = setInterval(intervalStuff, 1000)
+}
+
+function stopStuff() {
+    clearInterval(interval)
+}
+
+//------------------------------------------------------------------------------
+function intervalStuff() {
+    // add a timeout
+    setTimeout(function() { console.log("doing interval stuff")}, 333)
+    
+    // add a timeline marker
+    console.markTimeline("doing interval Stuff")
+    
+    // do an XHR
+    var xhr = new XMLHttpRequest()
+    // xhr.addEventListener("readystatechange", function() {logXhr(this)})
+    xhr.open("GET", "../target/target-script.js", true)
+    xhr.send()
+    
+    // cause an error
+    var empty = null
+    empty.x = 1
+    
+}
+
+//------------------------------------------------------------------------------
+function logXhr(xhr) {
+    console.log("xhr: readyState: " + xhr.readyState)
+}
+
diff --git a/weinre.web/index.html b/weinre.web/index.html
index 8e5e4d9..ac7e757 100644
--- a/weinre.web/index.html
+++ b/weinre.web/index.html
@@ -44,7 +44,7 @@
 <table>
 <tr><td>debug client user interface: <td> <span id="url-client-ui">???</span>
 <tr><td>documentation:               <td> <span id="url-target-documentation">???</span>
-<tr><td>target demo:                 <td> <span id="url-target-demo">???</span> <br><i>(<span id="url-target-demo-pieces"></span>)</i>
+<tr><td>target demo:                 <td> <span id="url-target-demo-min">???</span> <br><i>(<span id="url-target-demo-pieces"></span>)</i>
 </table>
 
 <h2>Target Bookmarklet</h2>
diff --git a/weinre.web/interfaces/interfaces.css b/weinre.web/interfaces/interfaces.css
index efeeecb..ee1a8c5 100644
--- a/weinre.web/interfaces/interfaces.css
+++ b/weinre.web/interfaces/interfaces.css
@@ -44,7 +44,7 @@
     white-space: pre;
 }
  
-.attributeName, .methodName {
+.attributeName, .methodName, .interfaceName {
     font-weight: bold;
 }
 
diff --git a/weinre.web/interfaces/interfaces.html b/weinre.web/interfaces/interfaces.html
index 55cd2f1..80a775c 100644
--- a/weinre.web/interfaces/interfaces.html
+++ b/weinre.web/interfaces/interfaces.html
@@ -16,6 +16,8 @@
         <script type="text/javascript">require("modjewel").warnOnRecursiveRequire(true)</script>
         <script src="/scooj.transportd.js"></script>
         <script src="/weinre/common/Weinre.transportd.js"></script>
+        <script src="/weinre/common/Ex.transportd.js"></script>
+        <script src="/weinre/common/StackTrace.transportd.js"></script>
         <script src="/weinre/common/IDLTools.transportd.js"></script>
         <script src="/weinre/common/Callback.transportd.js"></script>
         
diff --git a/weinre.web/interfaces/interfaces.js b/weinre.web/interfaces/interfaces.js
index aa181a3..206a562 100644
--- a/weinre.web/interfaces/interfaces.js
+++ b/weinre.web/interfaces/interfaces.js
@@ -32,8 +32,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function onLoad() {
     e_interfaceList  = document.getElementById("interface-list")
     e_interfaceName  = document.getElementById("interface-name")
@@ -47,8 +45,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function setUpShowCheckBoxes() {
     setUpShowCheckBox(e_showIdl,        "show-Idl")
     setUpShowCheckBox(e_showJavaScript, "show-JavaScript")
@@ -56,8 +52,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function setUpShowCheckBox(element, key) {
     var value = localStorage.getItem(key)
     if (null == value) 
@@ -72,8 +66,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function el_showCheckBoxClicked(event) {
     var element = event.target
     
@@ -83,8 +75,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function reapplyDisplayStyles() {
     reapplyDisplayStyle(".show-Idl",        e_showIdl.checked)
     reapplyDisplayStyle(".show-JavaScript", e_showJavaScript.checked)
@@ -92,8 +82,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function reapplyDisplayStyle(className, value) {
     value = value ? "block" : "none"
     ;[].slice.call(document.querySelectorAll(className)).forEach(function(element) {
@@ -102,8 +90,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function populateInterfacesList(intfs) {
     e_interfaceList.innerHTML = ""
         
@@ -133,8 +119,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function el_interfaceClicked(event) {
     event.preventDefault()
 
@@ -142,8 +126,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterface(interfaceName) {
     var intf = Interfaces[interfaceName]
     
@@ -163,8 +145,6 @@
 window.showInterface = showInterface
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceIdl(intf, html) {
     html.push("<div class='show-Idl'><h3>IDL</h3><pre>")
     html.push("interface {")
@@ -184,8 +164,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceIdlMethod(method, html) {
     var line = "\n   "
     
@@ -197,8 +175,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getIdlParameterList(parameters) {
     var result = []
     
@@ -218,8 +194,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getIdlType(type) {
     var result
     
@@ -239,8 +213,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 IDL2Java = {
     string: "String",
     any:    "Object",
@@ -250,8 +222,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaType(type) {
     var result
     
@@ -276,8 +246,6 @@
 
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceIdlAttribute(attribute, html) {
     var line = "<tr><td>" + Indent + "attribute "
         
@@ -288,11 +256,15 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceJavaScript(intf, html) {
     html.push("<div class='show-JavaScript'><h3>JavaScript</h3><pre>")
     
+    var line = ""
+        
+    line += "\n//-----------------------------------------------------------------------------"
+    line += "\n<span class='interfaceName'>class " + intf.name + "</span>"        
+    html.push(line)
+    
     intf.methods.forEach(function(method){
         showInterfaceJavaScriptMethod(intf, method, html)
     })
@@ -301,24 +273,18 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceJavaScriptMethod(intf, method, html) {
     var line = ""
         
     line += "\n//-----------------------------------------------------------------------------"
-    line += "\n//"
-    line += "\n//-----------------------------------------------------------------------------"
     line += "\n<span class='methodName'>method " + method.name + "</span>(" + getJavaScriptParameterListSimple(method.parameters, method.returns) + ")"
     line += "\n    // callback: function(" + getJavaScriptCallbackParameterListSimple(method.callbackParameters) + ")"
-    line += "\n    Weinre.notImplemented('" + intf.name + "::" + method.name + "()')"
+    line += "\n    Weinre.notImplemented(arguments.callee.signature)"
     line += "\n"
     html.push(line)
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaScriptParameterList(parameters, returnType) {
     var result = []
     
@@ -338,8 +304,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaScriptParameterListSimple(parameters, returnType) {
     var result = []
     
@@ -353,8 +317,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaScriptCallbackParameterListSimple(parameters) {
     var result = []
     
@@ -367,8 +329,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceJava(intf, html) {
     html.push("<div class='show-Java'><h3>Java</h3><pre>")
 
@@ -380,8 +340,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function showInterfaceJavaMethod(intf, method, html) {
     var line = ""
         
@@ -398,8 +356,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaParameterList(parameters, returnType) {
     var result = []
     
@@ -419,8 +375,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaParameterListSimple(parameters, returnType) {
     var result = []
 
@@ -436,8 +390,6 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getJavaCallbackParameterListSimple(parameters) {
     var result = []
     
@@ -454,27 +406,19 @@
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function toArray(arrayLike) {
     return [].slice.call(arrayLike)
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 ExBreak = new Error("breaks out of loops")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function exBreak() {
     throw ExBreak
 }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function allowExBreak(func) {
     try {
         func.call()
diff --git a/weinre.web/modules/weinre/client/Client.scoop b/weinre.web/modules/weinre/client/Client.scoop
index 7a8b8e9..08cb40f 100644
--- a/weinre.web/modules/weinre/client/Client.scoop
+++ b/weinre.web/modules/weinre/client/Client.scoop
@@ -6,150 +6,102 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/IDLTools
-require ../common/Callback
-require ../common/Weinre
-require ../common/Socket
-require ../common/Binding
+requireClass ../common/Native
 
-require ./InspectorBackendImpl
-require ./InspectorFrontendHostImpl
-require ./WeinreClientEventsImpl
-require ./RemotePanel
+requireClass ../common/IDLTools
+requireClass ../common/Callback
+requireClass ../common/Weinre
+requireClass ../common/MessageDispatcher
+requireClass ../common/Binding
 
-//-----------------------------------------------------------------------------
-// 
+requireClass ./InspectorBackendImpl
+requireClass ./InspectorFrontendHostImpl
+requireClass ./WeinreClientEventsImpl
+requireClass ./RemotePanel
+
 //-----------------------------------------------------------------------------
 class Client
-    this.initialize()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static
+init
     var AutoConnect = true
     
     Weinre.showNotImplemented()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static method autoConnect(value)
-    if (arguments.length >= 1) {
-        AutoConnect = !!value
-        
-        if (Client.uiAvailable) {
-            WebInspector.panels.remote.autoConnect(AutoConnect)
-        }
-    }
-
-    return AutoConnect
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method autoConnect(value)
-    if (arguments.length >= 1) {
-        return Client.autoConnect(value)
-    }
-    else {
-        return Client.autoConnect()
-    }
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method initialize
 
     // validate InspectorFrontendHost against IDL
-    IDLTools.validateAgainstIDL(InspectorFrontendHostImpl, 'InspectorFrontendHost')
+    // IDLTools.validateAgainstIDL(InspectorFrontendHostImpl, 'InspectorFrontendHost')
 
     // add a load handler for the window
     window.addEventListener("load", Binding(this, "onLoaded"), false)
 
     // create the socket
-    var webSocket = new Socket("../ws/client")
-    Weinre.webSocket = webSocket
+    var messageDispatcher = new MessageDispatcher("../ws/client")
+    Weinre.messageDispatcher = messageDispatcher
 
     // finish setting up InspectorBackend
     InspectorBackendImpl.setupProxies()
 
     // create the client commands proxy
-    Weinre.WeinreClientCommands = webSocket.createProxy("WeinreClientCommands")
+    Weinre.WeinreClientCommands = messageDispatcher.createProxy("WeinreClientCommands")
 
     // register WebInspector interface
-    webSocket.registerInterface("WebInspector", WebInspector, false)
+    messageDispatcher.registerInterface("WebInspector", WebInspector, false)
+    
+    // hack
+    WebInspector.mainResource = {}
+    WebInspector.mainResource.url = location.href
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method uiAvailable
     return WebInspector.panels && WebInspector.panels.remote
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method _installRemotePanelEventually
-    var self = this
-    
-    setTimeout(function() {
-        var wait = false
-        if (!WebInspector.applicationSettings) wait = true
-        
-        if (wait) {
-            self._installRemotePanelEventually()
-            return
-        }
-        
-        self._installRemotePanel()
-    }, 10)
+method autoConnect(value)
+    if (arguments.length >= 1) {
+        AutoConnect = !!value
+    }
 
+    return AutoConnect
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method _installRemotePanel
-
     WebInspector.panels.remote = new RemotePanel();
     
     var panel   = WebInspector.panels.remote;
-    panel.autoConnect(Client.autoConnect())
     
     var toolbar = document.getElementById("toolbar")
     WebInspector.addPanelToolbarIcon(toolbar, panel, toolbar.childNodes[1])
     
     WebInspector.currentPanel = panel
     
-    var panelsToClose = ["resources", "scripts", "timeline", "profiles", "storage", "audits"]
-    panelsToClose.forEach(function(panelToClose){
-        WebInspector.panels[panelToClose].toolbarItem.style.display = "none"
+    var toolButtonsToHide = ["scripts"]
+    toolButtonsToHide.forEach(function(toolButtonToHide){
+        if (!WebInspector.panels[toolButtonToHide]) return
+        if (!WebInspector.panels[toolButtonToHide].toolbarItem) return
+        WebInspector.panels[toolButtonToHide].toolbarItem.style.display = "none"
     })
     
     var button = document.getElementById("dock-status-bar-item")
     if (button) button.style.display = "none"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method onLoaded
 
-    // install Remote panel
-    this._installRemotePanelEventually()
+    this._installRemotePanel()
 
-    var webSocket = Weinre.webSocket
+    var messageDispatcher = Weinre.messageDispatcher
     
 //  Weinre.Socket.verbose(true)
     
-    webSocket.open()
-
-    webSocket.registerInterface("WeinreClientEvents",    new WeinreClientEventsImpl(this), true)
-    webSocket.registerInterface("InspectorFrontendHost", InspectorFrontendHost, true)
+    messageDispatcher.registerInterface("WeinreClientEvents",    new WeinreClientEventsImpl(this), false)
+    messageDispatcher.registerInterface("InspectorFrontendHost", InspectorFrontendHost, false)
 
     Weinre.WeinreClientCommands.registerClient(Binding(this, this.cb_registerClient))
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method cb_registerClient(clientId)
     Weinre.clientId = clientId
     Weinre.connectorId = clientId
@@ -160,22 +112,19 @@
         WebInspector.panels.remote.afterInitialConnection()
     }
     
-    Weinre.webSocket.getWebSocket().addEventListener("close", Binding(this, this.cb_webSocketClosed))
+    Weinre.messageDispatcher.getWebSocket().addEventListener("close", Binding(this, this.cb_webSocketClosed))
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method cb_webSocketClosed
     
     // use a delay, otherwise reloading will cause this stuff to flash
     // before page is actually reloaded
-    setTimeout(function() {
+    Native.setTimeout(function() {
         WebInspector.panels.remote.connectionClosed()
         WebInspector.currentPanel = WebInspector.panels.remote 
     }, 1000)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method main
     Weinre.client = new Client()
+    Weinre.client.initialize()
diff --git a/weinre.web/modules/weinre/client/ConnectorList.scoop b/weinre.web/modules/weinre/client/ConnectorList.scoop
index 37ebd65..92558cb 100644
--- a/weinre.web/modules/weinre/client/ConnectorList.scoop
+++ b/weinre.web/modules/weinre/client/ConnectorList.scoop
@@ -6,11 +6,9 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ./DOMTemplates as dt
+requireClass ./DOMTemplates as dt
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 class ConnectorList(title)
     this.connectors   = {}
     this.noneItem     = dt.LI("none")
@@ -20,14 +18,10 @@
     this.noneItem.addStyleClass("weinre-connector-item")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getElement
     return this.div
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method add(connector)
     if (this.connectors[connector.id]) return
     
@@ -39,7 +33,7 @@
         this.noneItem.style.display = "none"
     }
     
-    li.addStyleClass("fadeable")
+    li.addStyleClass("weinre-fadeable")
     
     var insertionPoint = this.getConnectorInsertionPoint(connector)
     if (!insertionPoint) {
@@ -50,8 +44,6 @@
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getNewestConnectorId(ignoring)
     var newest = 0
     
@@ -64,8 +56,6 @@
     return newest
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getConnectorInsertionPoint(connector)
     for (var i=0; i<this.ulConnectors.childNodes.length; i++) {
         var childNode = this.ulConnectors.childNodes[i]
@@ -78,8 +68,6 @@
     return null
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method remove(id, fast)
     var self = this
     var element = this.getConnectorElement(id)
@@ -98,7 +86,7 @@
 
     else {
         this.setState(element, "closed")
-        element.addStyleClass("fade")
+        element.addStyleClass("weinre-fade")
 
         window.setTimeout(function() {
             self._remove(element)
@@ -106,8 +94,6 @@
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _remove(element)
     this.ulConnectors.removeChild(element)
     if (this.getConnectors().length == 0) {
@@ -115,16 +101,12 @@
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method removeAll()
     this.getConnectors().forEach(function(connector) {
         this.remove(connector.id, true)
     }, this)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getConnectors()
     var result = []
     for (var id in this.connectors) {
@@ -136,8 +118,6 @@
     return result
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getConnectorElement(id)
     var connector = this.connectors[id]
     if (!connector) return null
@@ -145,8 +125,6 @@
     return connector.element
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method setCurrent(id)
     this.getConnectors().forEach(function(connector) {
         connector.element.removeStyleClass("current")
@@ -158,8 +136,6 @@
     element.addStyleClass("current")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method setState(id, state)
     if (typeof id == "string") {
         var element = this.getConnectorElement(id)
diff --git a/weinre.web/modules/weinre/client/DOMTemplates.scoop b/weinre.web/modules/weinre/client/DOMTemplates.scoop
index 9791b8c..566c1b4 100644
--- a/weinre.web/modules/weinre/client/DOMTemplates.scoop
+++ b/weinre.web/modules/weinre/client/DOMTemplates.scoop
@@ -7,7 +7,7 @@
  */
 
 //-----------------------------------------------------------------------------
-// creates functions of the form _H1_, _H2_, etc, that create a new element
+// creates functions of the form H1, H2, etc, as static methods that create a new element
 // of the specified name.  The function can take a variable number of arguments,
 // which are either child elements, strings, attributes, or properties of the element.
 //
@@ -19,48 +19,36 @@
 //      (the resulting property name doesn't include "$")
 //-----------------------------------------------------------------------------
 
-//-----------------------------------------------------------------------------
-//
+requireClass ../common/Ex
+
 //-----------------------------------------------------------------------------
 class DOMTemplates
 
-static 
-    var ElementNames = "H1 H2 H3 H4 H5 H6 UL OL DL LI DT DD SPAN DIV A B I TT P HR BR PRE IMG CANVAS TABLE TR TD FORM INPUT BUTTON SELECT OPTGROUP OPTION TEXTAREA"
-    ElementNames = ElementNames.split(" ")
-
-//-----------------------------------------------------------------------------
-//
 //-----------------------------------------------------------------------------
 function getElementFunction(elementName)
     return function() {
         var element = document.createElement(elementName)
         
-        var arguments = [].slice.call(arguments)
-        arguments.forEach(function(argument) {
+        var args = [].slice.call(arguments)
+        args.forEach(function(argument) {
             if      (argument.nodeType)           addToElement_Node(   element, argument )
             else if (typeof argument == "string") addToElement_String( element, argument )
             else if (typeof argument == "object") addToElement_Object( element, argument )
-            else throw new Error("invalid value passed to  DOMTemplates." + elementName + "(): " + argument)
+            else throw new Ex(arguments, "invalid value passed to  DOMTemplates." + elementName + "(): " + argument)
         })
         
         return element
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function addToElement_String(element, aString)
     addToElement_Node(element, document.createTextNode(aString))
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function addToElement_Node(element, anElement)
     element.appendChild(anElement)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function addToElement_Object(element, anObject)
     for (var key in anObject) {
         if (!anObject.hasOwnProperty(key)) continue
@@ -77,9 +65,10 @@
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static 
-    ElementNames.forEach(function(elementName) {
+init 
+    var elementNames = "H1 H2 H3 H4 H5 H6 UL OL DL LI DT DD SPAN DIV A B I TT P HR BR PRE IMG CANVAS TABLE TR TD FORM INPUT BUTTON SELECT OPTGROUP OPTION TEXTAREA"
+    elementNames = elementNames.split(" ")
+    
+    elementNames.forEach(function(elementName) {
         DOMTemplates[elementName] = getElementFunction(elementName)
     })
diff --git a/weinre.web/modules/weinre/client/InspectorBackendImpl.scoop b/weinre.web/modules/weinre/client/InspectorBackendImpl.scoop
index 5797f4b..a39ee09 100644
--- a/weinre.web/modules/weinre/client/InspectorBackendImpl.scoop
+++ b/weinre.web/modules/weinre/client/InspectorBackendImpl.scoop
@@ -6,34 +6,68 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/IDLTools
-require ../common/Weinre
+requireClass ../common/Ex
+requireClass ../common/IDLTools
+requireClass ../common/MessageDispatcher
+requireClass ../common/Weinre
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class InspectorBackendImpl
+    this.registeredDomainDispatchers = {}
+    MessageDispatcher.setInspectorBackend(this)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 static method setupProxies
-    var webInspectorHandlerIntfs = IDLTools.getIDLsMatching(/^WebInspector\w+Handler$/)
 
-    webInspectorHandlerIntfs.forEach(function(intf) {
-        var proxy = Weinre.webSocket.createProxy(intf.name)
+    var intfNames = [
+        "ApplicationCache",
+        "BrowserDebugger",
+        "CSS",
+        "Console",
+        "DOM",
+        "DOMStorage",
+        "Database",
+        "Debugger",
+        "InjectedScript",
+        "Inspector",
+        "Network",
+        "Profiler",
+        "Runtime"
+    ]
+
+    intfNames.forEach(function(intfName) {
+        var proxy = Weinre.messageDispatcher.createProxy(intfName)
+        if (window[intfName]) {
+            throw new Ex(arguments, "backend interface '" + intfName + "' already created")
+        }
+        
+        var intf = IDLTools.getIDL(intfName)
+        if (!intf) {
+            throw new Ex(arguments, "interface not registered: '" + intfName + "'")
+        }
+
+        window[intfName] = {}
         
         intf.methods.forEach(function(method) {
             var proxyMethod = InspectorBackendImpl.getProxyMethod(proxy, method)
             InspectorBackendImpl.prototype[method.name] = proxyMethod
+            window[intfName][method.name] = proxyMethod
         })
     })
+    
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 static method getProxyMethod(proxy, method)
     return function() {
         return proxy[method.name].apply(proxy, arguments)
     }
 
+//-----------------------------------------------------------------------------
+method registerDomainDispatcher(name, intf)
+    this.registeredDomainDispatchers[name] = intf
+    
+//-----------------------------------------------------------------------------
+method getRegisteredDomainDispatcher(name)
+    if (!this.registeredDomainDispatchers.hasOwnProperty(name)) return null
+    
+    return this.registeredDomainDispatchers[name]
diff --git a/weinre.web/modules/weinre/client/InspectorFrontendHostImpl.scoop b/weinre.web/modules/weinre/client/InspectorFrontendHostImpl.scoop
index a7b28c7..c121a96 100644
--- a/weinre.web/modules/weinre/client/InspectorFrontendHostImpl.scoop
+++ b/weinre.web/modules/weinre/client/InspectorFrontendHostImpl.scoop
@@ -6,126 +6,43 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Weinre
-require ../common/IDLTools
+requireClass ../common/Weinre
+requireClass ../common/IDLTools
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class InspectorFrontendHostImpl
         
     this._getPlatformAndPort()
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method loaded
-    WebInspector.Settings.initialize()
-    
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method closeWindow
-    Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method disconnectFromBackend
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method bringToFront
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method inspectedURLChanged(newURL)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method requestAttachWindow
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method requestDetachWindow
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method setAttachedWindowHeight(height)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method moveWindowBy(x, y)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method setExtensionAPI(script)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method localizedStringsURL
     return "nls/English.lproj/localizedStrings.js";
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method hiddenPanels
-//  return "audits,profiles,resources,scripts,timeline"
-    return ""
+    return "audits,profiles,resources,network"
+//    return "audits,profiles,resources,scripts,timeline,network"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method copyText(text)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method platform
     return "weinre"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method port
     return "weinre"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method showContextMenu(event, items)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method sendMessageToBackend(message)
     var object = JSON.parse(message)
     if (object[0] == "setInjectedScriptSource") {
         object[1] = "<long script elided>"
     }
-    console.log(arguments.callee.signature + "(" + JSON.stringify(object,null,4) + ")")
+    Weinre.logInfo(arguments.callee.signature + "(" + JSON.stringify(object,null,4) + ")")
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method _getPlatformAndPort
     this._platform       = "weinre"
     this._platformFlavor = "weinre"
diff --git a/weinre.web/modules/weinre/client/RemotePanel.scoop b/weinre.web/modules/weinre/client/RemotePanel.scoop
index db89c43..2c612ef 100644
--- a/weinre.web/modules/weinre/client/RemotePanel.scoop
+++ b/weinre.web/modules/weinre/client/RemotePanel.scoop
@@ -6,35 +6,20 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Binding
-require ../common/Weinre
+requireClass ../common/Binding
+requireClass ../common/Weinre
 
-require ./ConnectorList
-require ./DOMTemplates as dt
+requireClass ./ConnectorList
+requireClass ./DOMTemplates as dt
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class RemotePanel < WebInspector.Panel
     super("remote")
 
     this.initialize()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method autoConnect(value)
-    if (arguments.length >= 1) {
-        this._autoConnect = !!value
-    }
-
-    return this._autoConnect
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method initialize()
-    this.autoConnect(false)
     
     // main div
     var div = dt.DIV()
@@ -73,8 +58,6 @@
     this.reset();
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method addClient(client) 
     this.clientList.add(client)
     
@@ -100,20 +83,14 @@
     this.targetList.setState(id, state)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method getNewestTargetId(ignoring)
     return this.targetList.getNewestConnectorId(ignoring)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method afterInitialConnection
     this.clientList.afterInitialConnection()
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method reset
     this.clientList.removeAll()
     this.targetList.removeAll()
@@ -122,75 +99,55 @@
     Weinre.WeinreClientCommands.getClients(Binding(this, "cb_getClients"))
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method connectionClosed
     this.clientList.removeAll()
     this.targetList.removeAll()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method cb_getTargets(targets)
     targets.forEach(function(target) {
         this.addTarget(target)
     }, this)
    
-    if (!this.autoConnect()) return
+    if (!Weinre.client.autoConnect()) return
     
     var newestTargetId = this.getNewestTargetId()
     if (!newestTargetId) return
     
-    Weinre.WeinreClientCommands.connectTarget(Weinre.clientId, newestTargetId)
+    Weinre.WeinreClientCommands.connectTarget(Weinre.connectorId, newestTargetId)
     
     
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method cb_getClients(clients)
     clients.forEach(function(client) {
         this.addClient(client)
     }, this)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 getter toolbarItemClass
     return "remote"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 getter toolbarItemLabel
     return "Remote"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 getter statusBarItems
     return []
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 getter defaultFocusedElement
     return this.contentElement
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method show
     super()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method hide()
     super()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method setServerProperties(properties)
     var table = "<table>"
     var keys = []
@@ -220,14 +177,10 @@
 //=============================================================================
     
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 class TargetList < ConnectorList
     super("Targets")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getListItem(target)
     var self = this
     var text = target.hostName + " [id: " + target.id + "]" + " - " + target.url 
@@ -247,8 +200,6 @@
     return item
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method connectToTarget(targetId, event)
     if (event) {
         event.preventDefault()
@@ -267,23 +218,17 @@
 //=============================================================================
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 class ClientList < ConnectorList
     super("Clients")
 
     this.noneItem.innerHTML = "Waiting for connection..."
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method afterInitialConnection()
     this.noneItem.innerHTML = "Connection lost, reload this page to reconnect."
     this.noneItem.addStyleClass("error")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getListItem(client)
     var text = client.hostName + " [id: " + client.id + "]"
     
diff --git a/weinre.web/modules/weinre/client/WeinreClientEventsImpl.scoop b/weinre.web/modules/weinre/client/WeinreClientEventsImpl.scoop
index 9b59e0c..c58fbb0 100644
--- a/weinre.web/modules/weinre/client/WeinreClientEventsImpl.scoop
+++ b/weinre.web/modules/weinre/client/WeinreClientEventsImpl.scoop
@@ -6,54 +6,42 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Callback
-require ../common/Weinre
+requireClass ../common/Callback
+requireClass ../common/Weinre
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class WeinreClientEventsImpl(client)
     this.client = client
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method clientRegistered(clientDescription)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.addClient(clientDescription)
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method targetRegistered(targetDescription)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.addTarget(targetDescription)
     }
     
-    if (!this.client.autoConnect()) return
+    if (!Weinre.client.autoConnect()) return
     
     Weinre.WeinreClientCommands.connectTarget(Weinre.clientId, targetDescription.id)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method clientUnregistered(/*int*/ clientId)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.removeClient(clientId)
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method targetUnregistered(/*int*/ targetId)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.removeTarget(targetId)
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method connectionCreated(/*int*/ clientId, /*int*/ targetId)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.setClientState(clientId, "connected") 
@@ -63,10 +51,11 @@
     if (clientId != Weinre.clientId) return
 
     Weinre.targetId = targetId
+    
+    WebInspector.panels.elements.reset()
+    WebInspector.panels.timeline._clearPanel()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method connectionDestroyed(/*int*/ clientId, /*int*/ targetId)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.setClientState(clientId, "not-connected") 
@@ -77,24 +66,20 @@
     
     Weinre.targetId = null
     
-    if (!this.client.autoConnect()) return
+    if (!Weinre.client.autoConnect()) return
     if (!this.client.uiAvailable()) return
     
     var nextTargetId = WebInspector.panels.remote.getNewestTargetId(targetId)
     if (!nextTargetId) return
     
     Weinre.WeinreClientCommands.connectTarget(Weinre.clientId, nextTargetId)
-    console.log("autoconnecting to " + nextTargetId)
+    Weinre.logInfo("autoconnecting to " + nextTargetId)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method sendCallback(/*int*/ callbackId, /*any*/ result)
     Callback.invoke(callbackId, result)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method serverProperties(/*any*/ properties)
     if (this.client.uiAvailable()) {
         WebInspector.panels.remote.setServerProperties(properties)
diff --git a/weinre.web/modules/weinre/common/Binding.scoop b/weinre.web/modules/weinre/common/Binding.scoop
index a5c55d5..9db156b 100644
--- a/weinre.web/modules/weinre/common/Binding.scoop
+++ b/weinre.web/modules/weinre/common/Binding.scoop
@@ -6,14 +6,14 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-//-----------------------------------------------------------------------------
-//
+requireClass ./Ex
+
 //-----------------------------------------------------------------------------
 class Binding(receiver, method)
 
-    if (receiver == null) throw new Error("receiver argument for Binding constructor was null")
+    if (receiver == null) throw new Ex(arguments, "receiver argument for Binding constructor was null")
     if (typeof(method) == "string") method = receiver[method]
-    if (typeof(method) != "function") throw new Error("method argument didn't specify a function")
+    if (typeof(method) != "function") throw new Ex(arguments, "method argument didn't specify a function")
 
     return function() {
         return method.apply(receiver, [].slice.call(arguments))
diff --git a/weinre.web/modules/weinre/common/Callback.scoop b/weinre.web/modules/weinre/common/Callback.scoop
index 8aef9c9..b355714 100644
--- a/weinre.web/modules/weinre/common/Callback.scoop
+++ b/weinre.web/modules/weinre/common/Callback.scoop
@@ -6,39 +6,33 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class Callback
-    throw new Error("this class is not intended to be instantiated")
+requireClass ./Ex
 
 //-----------------------------------------------------------------------------
-//
+class Callback
+    throw new Ex(arguments, "this class is not intended to be instantiated")
+
 //-----------------------------------------------------------------------------
-static 
+init 
     var CallbackTable = {}
     var CallbackIndex = 1
     var ConnectorId   = "???"
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method setConnectorId(connectorId)
-    ConnectorId = connectorId
+    ConnectorId = ""  + connectorId
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method register(callback)
     if (typeof callback == "function") callback = [null, callback]
-    if (typeof callback.slice != "function") throw new Error("callback must be an array or function")
+    if (typeof callback.slice != "function") throw new Ex(arguments, "callback must be an array or function")
     
     var receiver = callback[0]
     var func     = callback[1]
     var data     = callback.slice(2)
     
     if (typeof func == "string") func = receiver.func
-    if (typeof func != "function") throw new Error("callback function was null or not found")
+    if (typeof func != "function") throw new Ex(arguments, "callback function was null or not found")
 
     var index = ConnectorId + "::" + CallbackIndex
     
@@ -50,17 +44,13 @@
     return index
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method deregister(index)
     delete CallbackTable[index]
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method invoke(index, args)
     var callback = CallbackTable[index]
-    if (!callback) throw new Error("callback " + index + " not registered or already invoked")
+    if (!callback) throw new Ex(arguments, "callback " + index + " not registered or already invoked")
     
     var receiver = callback[0]
     var func     = callback[1]
@@ -72,7 +62,7 @@
     catch (e) {
         var funcName = func.name
         if (!funcName) funcName = "<unnamed>"
-        console.log(arguments.callee.signature + " exception invoking callback: " + funcName + "(" + args.join(",") + "): " + e)
+        require("./Weinre").logError(arguments.callee.signature + " exception invoking callback: " + funcName + "(" + args.join(",") + "): " + e)
     }
     finally {
         Callback.deregister(index)
diff --git a/weinre.web/modules/weinre/common/EventListeners.scoop b/weinre.web/modules/weinre/common/EventListeners.scoop
index 30befbc..0c9d987 100644
--- a/weinre.web/modules/weinre/common/EventListeners.scoop
+++ b/weinre.web/modules/weinre/common/EventListeners.scoop
@@ -6,21 +6,18 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-//-----------------------------------------------------------------------------
-//
+requireClass ./Ex
+requireClass ./Weinre
+
 //-----------------------------------------------------------------------------
 class EventListeners
     this._listeners = []
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method add(listener, useCapture)
     this._listeners.push([listener, useCapture])
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method remove(listener, useCapture)
     for (var i=0; i<this._listeners.length; i++) {
         var listener = this._listeners[i]
@@ -32,8 +29,6 @@
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method fire(event)
     this._listeners.slice().forEach(function(listener) {
         var listener = listener[0]
@@ -43,19 +38,19 @@
                 listener.call(null, event)
             }
             catch(e) {
-                console.log(arguments.callee.signature + " invocation exception: " + e)
+                Weinre.logError(arguments.callee.signature + " invocation exception: " + e)
             }
             return
         }
         
         if (typeof listener.handleEvent != "function") {
-            throw new Error("listener does not implement the handleEvent() method")
+            throw new Ex(arguments, "listener does not implement the handleEvent() method")
         }
         
         try {
             listener.handleEvent.call(listener, event)
         }
         catch(e) {
-            console.log(arguments.callee.signature + " invocation exception: " + e)
+            Weinre.logError(arguments.callee.signature + " invocation exception: " + e)
         }
     })
diff --git a/weinre.web/modules/weinre/common/Ex.scoop b/weinre.web/modules/weinre/common/Ex.scoop
new file mode 100644
index 0000000..e6d0bf7
--- /dev/null
+++ b/weinre.web/modules/weinre/common/Ex.scoop
@@ -0,0 +1,30 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2010, 2011 IBM Corporation
+ */
+
+requireClass ./StackTrace
+
+//-----------------------------------------------------------------------------
+class Ex(args, message)
+    if (!args || !args.callee) {
+        throw Ex(arguments, "first parameter must be an Arguments object") 
+    }
+    
+    StackTrace.dump(args)
+    
+    if (message instanceof Error) {
+        message = "threw error: " + message
+    }
+    
+    return new Error(prefix(args, message))
+    
+//-----------------------------------------------------------------------------
+function prefix(args, string)
+    if (args.callee.signature)   return args.callee.signature +   ": " + string
+    if (args.callee.displayName) return args.callee.displayName + ": " + string
+    if (args.callee.name)        return args.callee.name +        ": " + string
+    return "<anonymous>" +                                        ": " + string
diff --git a/weinre.web/modules/weinre/common/IDGenerator.scoop b/weinre.web/modules/weinre/common/IDGenerator.scoop
new file mode 100644
index 0000000..0b91770
--- /dev/null
+++ b/weinre.web/modules/weinre/common/IDGenerator.scoop
@@ -0,0 +1,20 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+//-----------------------------------------------------------------------------
+class IDGenerator
+
+//-----------------------------------------------------------------------------
+init
+    var nextId = 1
+
+//-----------------------------------------------------------------------------
+static method next
+    var result = nextId
+    nextId += 1
+    return result
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/common/IDLTools.scoop b/weinre.web/modules/weinre/common/IDLTools.scoop
index c60820a..6e6f856 100644
--- a/weinre.web/modules/weinre/common/IDLTools.scoop
+++ b/weinre.web/modules/weinre/common/IDLTools.scoop
@@ -6,24 +6,19 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ./Callback
+requireClass ./Ex
+requireClass ./Callback
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 class IDLTools
-    throw new Error("this class is not intended to be instantiated")
+    throw new Ex(arguments, "this class is not intended to be instantiated")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static
+init
     var IDLs = {}
     IDLTools._idls = IDLs
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method addIDLs(idls)
     idls.forEach(function(idl){
         idl.interfaces.forEach(function(intf){
@@ -33,14 +28,10 @@
     })
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method getIDL(name)
     return IDLs[name]
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method getIDLsMatching(regex)
     var results = []
     
@@ -53,12 +44,10 @@
     return results
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method validateAgainstIDL(klass, interfaceName)
     var intf = IDLTools.getIDL(interfaceName)
     var messagePrefix = "IDL validation for " + interfaceName + ": "
-    if (null == intf) throw new Error(messagePrefix + "idl not found: '" + interfaceName + "'")
+    if (null == intf) throw new Ex(arguments, messagePrefix + "idl not found: '" + interfaceName + "'")
     
     var errors = []
     // check that class implements all the methods
@@ -95,24 +84,20 @@
     if (!errors.length) return
     
     errors.forEach(function(error){
-        console.log(error)
+        require("./Weinre").logError(error)
     })
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method buildProxyForIDL(proxyObject, interfaceName)
     var intf = IDLTools.getIDL(interfaceName)
     var messagePrefix = "building proxy for IDL " + interfaceName + ": "
-    if (null == intf) throw new Error(messagePrefix + "idl not found: '" + interfaceName + "'")
+    if (null == intf) throw new Ex(arguments, messagePrefix + "idl not found: '" + interfaceName + "'")
     
     intf.methods.forEach(function(intfMethod) {
         proxyObject[intfMethod.name] = getProxyMethod(intf, intfMethod)
     })
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function getProxyMethod(intf, method)
     var result = function proxyMethod() {
         var callbackId = null
diff --git a/weinre.web/modules/weinre/common/Socket.scoop b/weinre.web/modules/weinre/common/MessageDispatcher.scoop
similarity index 61%
rename from weinre.web/modules/weinre/common/Socket.scoop
rename to weinre.web/modules/weinre/common/MessageDispatcher.scoop
index b25d17f..f6adc72 100644
--- a/weinre.web/modules/weinre/common/Socket.scoop
+++ b/weinre.web/modules/weinre/common/MessageDispatcher.scoop
@@ -6,15 +6,14 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ./Weinre
-require ./WebSocketXhr
-require ./IDLTools
-require ./Binding
+requireClass ./Weinre
+requireClass ./WebSocketXhr
+requireClass ./IDLTools
+requireClass ./Binding
+requireClass ./Ex
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-class Socket(url)
+class MessageDispatcher(url)
     this._url        = url
     
     this.error       = null
@@ -22,15 +21,18 @@
     this._opened     = false
     this._closed     = false
     this._interfaces = {}
+    
+    this._open()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static
+init
     var Verbose = false
+    var InspectorBackend
 
 //-----------------------------------------------------------------------------
-//
+static method setInspectorBackend(inspectorBackend)
+    InspectorBackend = inspectorBackend
+    
 //-----------------------------------------------------------------------------
 static method verbose(value)
     if (arguments.length >= 1) {
@@ -40,11 +42,9 @@
     return Verbose
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method open
+method _open
     if (this._opened || this._opening) return
-    if (this._closed) throw new Error("socket has already been closed")
+    if (this._closed) throw new Ex(arguments, "socket has already been closed")
     
     this._opening = true 
     this._socket = new WebSocketXhr(this._url)
@@ -54,8 +54,6 @@
     this._socket.addEventListener("close",   Binding(this, "_handleClose"))
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method close
     if (this._closed) return
     
@@ -65,30 +63,22 @@
     this._socket.close()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method send(data)
     this._socket.send(data)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getWebSocket
     return this._socket
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method registerInterface(intfName, intf, validate)
     if (validate) IDLTools.validateAgainstIDL(intf.constructor, intfName)
     
-    if (this._interfaces[intfName]) throw new Error("interface " + intfName + " has already been registered")
+    if (this._interfaces[intfName]) throw new Ex(arguments, "interface " + intfName + " has already been registered")
     
     this._interfaces[intfName] = intf
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method createProxy(intfName)
     var proxy = {}
     
@@ -102,11 +92,9 @@
     return proxy
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _sendMethodInvocation(intfName, methodName, args)
-    if (typeof intfName   != "string") throw new Error("expecting intf parameter to be a string")
-    if (typeof methodName != "string") throw new Error("expecting method parameter to be a string")
+    if (typeof intfName   != "string") throw new Ex(arguments, "expecting intf parameter to be a string")
+    if (typeof methodName != "string") throw new Ex(arguments, "expecting method parameter to be a string")
     
     var data = {
             "interface": intfName,
@@ -119,12 +107,10 @@
     this._socket.send(data)
     
     if (Verbose) {
-        console.log(this.constructor.name + "[" + this._url + "]: send " + intfName + "." + methodName + "(" + JSON.stringify(args) + ")")
+        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: send " + intfName + "." + methodName + "(" + JSON.stringify(args) + ")")
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getState
     if (this._opening) return "opening"
     if (this._opened)  return "opened"
@@ -132,36 +118,28 @@
     return "unknown"
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method isOpen
     return this._opened == true
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleOpen
     this._opening = false
     this._opened  = true
     
     if (Verbose) {
-        console.log(this.constructor.name + "[" + this._url + "]: opened")
+        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: opened")
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleError(message)
     this.error = message
     this.close()
 
     if (Verbose) {
-        console.log(this.constructor.name + "[" + this._url + "]: error: " + message)
+        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: error: " + message)
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleMessage(message)
     var data
     
@@ -169,7 +147,7 @@
         data = JSON.parse(message.data)
     }
     catch (e) {
-        throw new Error("invalid JSON data received: " + e + ": '" + message.data + "'")
+        throw new Ex(arguments, "invalid JSON data received: " + e + ": '" + message.data + "'")
     }
 
     var intfName   = data["interface"]
@@ -178,29 +156,40 @@
 
     var methodSignature = intfName + "." + methodName + "()"
     
-    var intf = this._interfaces[intfName]
-    if (!intf) throw new Error("request for non-registered interface:" + methodSignature)
+    var intf = this._interfaces.hasOwnProperty(intfName) && this._interfaces[intfName]
+    
+    if (!intf && InspectorBackend && intfName.match(/.*Notify/)) {
+        intf = InspectorBackend.getRegisteredDomainDispatcher(intfName.substr(0,intfName.length-6))
+    }
+    
+    if (!intf) {
+        Weinre.logWarning("weinre: request for non-registered interface:" + methodSignature)
+        return
+    }
+    
+    methodSignature = intf.constructor.name + "." + methodName + "()"
     
     var method = intf[methodName]
-    if (typeof method != "function") throw new Error("request for unknown method on interface: " + methodSignature)
+    if (typeof method != "function") {
+        Weinre.notImplemented(methodSignature)
+        return
+    }
     
     try {
         method.apply(intf, args)
     }
     catch (e) {
-        console.log("Weinre.Socket._handleMessage() invocation exception: " + e)
+        Weinre.logError("weinre: invocation exception on " + methodSignature + ": " + e)
     }
     
     if (Verbose) {
-        console.log(this.constructor.name + "[" + this._url + "]: recv " + intfName + "." + methodName + "(" + JSON.stringify(args) + ")")
+        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: recv " + intfName + "." + methodName + "(" + JSON.stringify(args) + ")")
     }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleClose
     this._reallyClosed = true
     
     if (Verbose) {
-        console.log(this.constructor.name + "[" + this._url + "]: closed")
+        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: closed")
     }
diff --git a/weinre.web/modules/weinre/common/Native.scoop b/weinre.web/modules/weinre/common/Native.scoop
new file mode 100644
index 0000000..cc8ce08
--- /dev/null
+++ b/weinre.web/modules/weinre/common/Native.scoop
@@ -0,0 +1,29 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+//-----------------------------------------------------------------------------
+class Native
+
+//-----------------------------------------------------------------------------
+init
+    Native.original = {}
+
+    Native.original.clearInterval       = window.clearInterval
+    Native.original.clearTimeout        = window.clearTimeout
+    Native.original.setTimeout          = window.setTimeout
+    Native.original.setInterval         = window.setInterval
+    Native.original.XMLHttpRequest      = window.XMLHttpRequest
+    Native.original.XMLHttpRequest_open = window.XMLHttpRequest.prototype.open
+
+    Native.clearInterval       = function() { return Native.original.clearInterval.apply( window, [].slice.call(arguments))}
+    Native.clearTimeout        = function() { return Native.original.clearTimeout.apply(  window, [].slice.call(arguments))}
+    Native.setInterval         = function() { return Native.original.setInterval.apply(   window, [].slice.call(arguments))}
+    Native.setTimeout          = function() { return Native.original.setTimeout.apply(    window, [].slice.call(arguments))}
+    Native.XMLHttpRequest      = function() { return new Native.original.XMLHttpRequest()}
+    Native.XMLHttpRequest_open = function() { return Native.original.XMLHttpRequest_open.apply(this, [].slice.call(arguments))}
+    
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/common/StackTrace.scoop b/weinre.web/modules/weinre/common/StackTrace.scoop
new file mode 100644
index 0000000..a46b602
--- /dev/null
+++ b/weinre.web/modules/weinre/common/StackTrace.scoop
@@ -0,0 +1,55 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2010, 2011 IBM Corporation
+ */
+
+//-----------------------------------------------------------------------------
+class StackTrace(args)
+    if (!args || !args.callee) {
+        throw Error("first parameter to " + arguments.callee.signature + " must be an Arguments object") 
+    }
+    
+    this.trace = getTrace(args)
+
+//-----------------------------------------------------------------------------
+static method dump(args)
+    args = args || arguments
+    
+    var stackTrace = new StackTrace(args)
+    stackTrace.dump()
+
+//-----------------------------------------------------------------------------
+method dump
+    console.log("StackTrace:")
+    this.trace.forEach(function(frame) {
+        console.log("    " + frame)
+    })
+    
+//-----------------------------------------------------------------------------
+function getTrace(args)
+
+    var result = []
+    var visitedFuncs = []
+    
+    var func = args.callee
+    
+    while (func) {
+        if      (func.signature)   result.push(func.signature)
+        else if (func.displayName) result.push(func.displayName)
+        else if (func.name)        result.push(func.name)
+        else result.push("<anonymous>")
+
+        if (-1 != visitedFuncs.indexOf(func)) {
+            result.push("... recursion")
+            return result
+        }
+        
+        visitedFuncs.push(func)
+        
+        func = func.caller
+    }
+    
+    return result
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/common/WebSocketXhr.scoop b/weinre.web/modules/weinre/common/WebSocketXhr.scoop
index 29d24eb..0eb5132 100644
--- a/weinre.web/modules/weinre/common/WebSocketXhr.scoop
+++ b/weinre.web/modules/weinre/common/WebSocketXhr.scoop
@@ -6,27 +6,25 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ./Weinre
-require ./EventListeners
+requireClass ./Ex
+requireClass ./Weinre
+requireClass ./EventListeners
+requireClass ./Native
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 class WebSocketXhr(url)
     this.initialize(url)
     
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static
+init
+    var XMLHttpRequest = Native.XMLHttpRequest
+    
     WebSocketXhr.CONNECTING = 0
     WebSocketXhr.OPEN       = 1
     WebSocketXhr.CLOSING    = 2
     WebSocketXhr.CLOSED     = 3
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method initialize(url)
     this.readyState      = WebSocketXhr.CONNECTING 
     this._url            = url
@@ -44,14 +42,10 @@
     this._getChannel()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _getChannel
     this._xhr(this._url, "POST", "", this._handleXhrResponseGetChannel)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleXhrResponseGetChannel(xhr)
     if (xhr.status != 200) return this._handleXhrResponseError(xhr)
 
@@ -70,7 +64,7 @@
         return
     }
     
-    Weinre.connectorId = object.channel
+    Weinre.connectorId = "" + object.channel
     
     this._urlChannel = this._url + "/" + object.channel
     this.readyState = WebSocketXhr.OPEN
@@ -83,8 +77,6 @@
     this._readLoop()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _readLoop
     if (this.readyState == WebSocketXhr.CLOSED) return
     if (this.readyState == WebSocketXhr.CLOSING) return
@@ -92,8 +84,6 @@
     this._xhr(this._urlChannel, "GET", "", this._handleXhrResponseGet)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleXhrResponseGet(xhr)
     var self = this
     
@@ -111,17 +101,15 @@
         return
     }
     
-    window.setTimeout(function() {self._readLoop()}, 0)
+    Native.setTimeout(function() {self._readLoop()}, 0)
 
     datum.forEach(function(data) {
         self._fireEventListeners("message", {data: data})
     })
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method send(data)
-    if (typeof data != "string") throw new Error(this.constructor.name + "." + this.caller)
+    if (typeof data != "string") throw new Ex(arguments, this.constructor.name + "." + this.caller)
 
     this._queuedSends.push(data)
     
@@ -129,8 +117,6 @@
     this._sendQueued();
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _sendQueued
     if (this._queuedSends.length == 0) return
     if (this.readyState == WebSocketXhr.CLOSED) return
@@ -144,19 +130,15 @@
     this._xhr(this._urlChannel, "POST", datum, this._handleXhrResponseSend)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleXhrResponseSend(xhr)
     var httpSocket = this
     
     if (xhr.status != 200) return this._handleXhrResponseError(xhr)
     
     this._sendInProgress = false
-    window.setTimeout(function() {httpSocket._sendQueued()}, 0)
+    Native.setTimeout(function() {httpSocket._sendQueued()}, 0)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method close
     this._sendInProgress = true
     this.readyState = WebSocketXhr.CLOSING
@@ -167,20 +149,14 @@
     this.readyState = WebSocketXhr.CLOSED
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method addEventListener(type, listener, useCapture)
     this._getListeners(type).add(listener, useCapture)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method removeEventListener(type, listener, useCapture)
     this._getListeners(type).remove(listener, useCapture)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _fireEventListeners(type, event)
     if (this.readyState == WebSocketXhr.CLOSED) return
     
@@ -188,17 +164,13 @@
     this._getListeners(type).fire(event)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _getListeners(type)
     var listeners = this._listeners[type]
-    if (null == listeners) throw new Error("invalid event listener type: '" + type + "'")
+    if (null == listeners) throw new Ex(arguments, "invalid event listener type: '" + type + "'")
     
     return listeners
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _handleXhrResponseError(xhr)
     if (xhr.status == 404) {
         this.close()
@@ -211,13 +183,11 @@
         message: "error from XHR invocation: " + xhr.statusText
     })
     
-    console.log("error from XHR invocation: " + xhr.status + ": " + xhr.statusText)
+    Weinre.logError("error from XHR invocation: " + xhr.status + ": " + xhr.statusText)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _xhr(url, method, data, handler)
-    if (null == handler) throw new Error("handler must not be null")
+    if (null == handler) throw new Ex(arguments, "handler must not be null")
     
     var xhr = new XMLHttpRequest()
     
@@ -230,8 +200,6 @@
     xhr.send(data)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 function _xhrEventHandler(event)
     var xhr = event.target
     if (xhr.readyState != 4) return
diff --git a/weinre.web/modules/weinre/common/Weinre.scoop b/weinre.web/modules/weinre/common/Weinre.scoop
index 26f8766..75c37d0 100644
--- a/weinre.web/modules/weinre/common/Weinre.scoop
+++ b/weinre.web/modules/weinre/common/Weinre.scoop
@@ -6,29 +6,37 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ./IDLTools
+requireClass ./Ex
+requireClass ./IDLTools
+requireClass ./StackTrace
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 class Weinre
-    throw new Error("this class is not intended to be instantiated")
+    throw new Ex(arguments, "this class is not intended to be instantiated")
 
 //-----------------------------------------------------------------------------
-//
+init 
+    var _notImplemented     = {}
+    var _showNotImplemented = false
+    var CSSProperties       = []
+    var logger              = null
+
 //-----------------------------------------------------------------------------
 static method addIDLs(idls)
     IDLTools.addIDLs(idls)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-static 
-    var _notImplemented     = {}
-    var _showNotImplemented = false
+static method addCSSProperties(cssProperties)
+    CSSProperties = cssProperties
 
 //-----------------------------------------------------------------------------
-//
+static method getCSSProperties
+    return CSSProperties
+
+//-----------------------------------------------------------------------------
+static method deprecated()
+    StackTrace.dump(arguments)
+    
 //-----------------------------------------------------------------------------
 static method notImplemented(thing)
     if (_notImplemented[thing]) return
@@ -36,13 +44,37 @@
     _notImplemented[thing] = true
     
     if (!_showNotImplemented) return
-    console.log(thing + " not implemented")
+    Weinre.logWarning(thing + " not implemented")
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method showNotImplemented()
     _showNotImplemented = true
     for (var key in _notImplemented) {
-        console.log(key + " not implemented")
-    }
\ No newline at end of file
+        Weinre.logWarning(key + " not implemented")
+    }
+    
+//-----------------------------------------------------------------------------
+static method logError(message)
+    getLogger().logError(message)
+
+//-----------------------------------------------------------------------------
+static method logWarning(message)
+    getLogger().logWarning(message)
+
+//-----------------------------------------------------------------------------
+static method logInfo(message)
+    getLogger().logInfo(message)
+
+//-----------------------------------------------------------------------------
+static method logDebug(message)
+    getLogger().logDebug(message)
+
+//-----------------------------------------------------------------------------
+function getLogger()
+    if (logger) return logger
+    
+    if      (Weinre.client) logger = Weinre.WeinreClientCommands
+    else if (Weinre.target) logger = Weinre.WeinreTargetCommands
+    
+    return logger
+    
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/target/CSSStore.scoop b/weinre.web/modules/weinre/target/CSSStore.scoop
index d4d3b6e..3f1edf7 100644
--- a/weinre.web/modules/weinre/target/CSSStore.scoop
+++ b/weinre.web/modules/weinre/target/CSSStore.scoop
@@ -7,33 +7,23 @@
  */
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class CSSStore
     this.__styleMap    = {}
     this.__nextId      = 0
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-static
+init
     var Properties = []
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method addCSSProperties(properties)
     Properties = properties
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getStyle(styleId)
     return this.__styleMap[styleId]
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getStyleId(style)
     if (style.__weinre_id) { 
         return style.__weinre_id
@@ -45,52 +35,65 @@
     return style.__weinre_id
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getInlineStyle(node)
-    return 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"
+    }
+    return styleObject
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getComputedStyle(node)
     if (!node) return {}
     if (node.nodeType != Node.ELEMENT_NODE) return {}
     
-    return this.buildObjectForStyle(window.getComputedStyle(node), false)
+    var styleObject = this.buildObjectForStyle(window.getComputedStyle(node), false)
+    return styleObject
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getMatchedCSSRules(node)
     var result = []
     
+    for (var i=0; i<document.styleSheets.length; i++) {
+        var cssStyleSheet = document.styleSheets[i]
+        
+        if (!cssStyleSheet.cssRules) continue
+        
+        for (var j=0; j<cssStyleSheet.cssRules.length; j++) {
+            var cssRule = cssStyleSheet.cssRules[j]
+            
+            if (!elementMatchesSelector(node, cssRule.selectorText)) continue
+            
+            var object = {}
+            
+            object.ruleId = this.getStyleId(cssRule)
+            object.selectorText = cssRule.selectorText
+            object.style = this.buildObjectForStyle(cssRule.style, true)
+            result.push(object)
+        }
+    }
+    
     return result
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getStyleAttributes(node)
     var result = {}
     
     return result
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getPseudoElements(node)
     var result = []
     
     return result
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method buildObjectForStyle(style, bind)
     var result = {
-        width:      null,
-        height:     null,
-        properties: []
+        width:         null,
+        height:        null,
+        properties:    [],
+        cssProperties: []
     }
     
     if (!style) return result
@@ -118,8 +121,6 @@
     return result
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method populateObjectWithStyleProperties(style, result)
     var properties = []
     var shorthandValues = {}
@@ -133,25 +134,40 @@
             property.name = name
             property.priority = style.getPropertyPriority(name)
             property.implicit = false // style.isPropertyImplicit(name)
-            // String shorthand = style->getPropertyShorthand(name);
             property.shorthand = ""
-                /*
-        if (!shorthand.isEmpty() && !foundShorthands.contains(shorthand)) {
-            foundShorthands.add(shorthand);
-            shorthandValues->setString(shorthand, shorthandValue(style, shorthand));
-        }
-                 */
-                property.value = style.getPropertyValue(name)
+            property.status    = "active"
+            property.parsedOk  = true
+            property.value     = style.getPropertyValue(name)
 
-                properties.push(property);
+            properties.push(property);
         }
     }
     
-    result.properties      = properties
+    result.cssProperties   = properties
     result.shorthandValues = shorthandValues
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method _nextId
     return "" + (++this.__nextId)
+    
+//-----------------------------------------------------------------------------
+function mozMatchesSelector(element, selector)
+    if (!element.mozMatchesSelector) return false
+    return element.mozMatchesSelector(selector)
+
+//-----------------------------------------------------------------------------
+function webkitMatchesSelector(element, selector)
+    if (!element.webkitMatchesSelector) return false
+    return element.webkitMatchesSelector(selector)
+
+//-----------------------------------------------------------------------------
+function fallbackMatchesSelector(element, selector)
+    return false
+    
+//-----------------------------------------------------------------------------
+init
+    var elementMatchesSelector
+    
+    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/Console.scoop b/weinre.web/modules/weinre/target/Console.scoop
index 9a093df..e796a02 100644
--- a/weinre.web/modules/weinre/target/Console.scoop
+++ b/weinre.web/modules/weinre/target/Console.scoop
@@ -6,17 +6,14 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Weinre
+requireClass ../common/Weinre
+requireClass ../target/Timeline
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class Console
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-static
+init
     var UsingRemote = false
     
     var RemoteConsole   = new Console()
@@ -54,9 +51,6 @@
         Debug: 4
     }
 
-
-//-----------------------------------------------------------------------------
-// 
 //-----------------------------------------------------------------------------
 static method useRemote(value)
     if (arguments.length == 0) return UsingRemote
@@ -73,130 +67,91 @@
     return oldValue
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method log
-    var messageParts = []
-    
-    for (var i=0; i<arguments.length; i++) {
-        messageParts.push(arguments[i].toString())
-    }
+method _generic(level, messageParts)
     
     var message = messageParts.join(" ")
     
     var payload = {
         source:      MessageSource.JS,
         type:        MessageType.Log,
-        level:       MessageLevel.Log,
+        level:       level,
         message:     message
     }
     
-    WebInspector.addConsoleMessage(payload)
+    Weinre.wi.ConsoleNotify.addConsoleMessage(payload)
 
 //-----------------------------------------------------------------------------
-// 
+method log
+    this._generic(MessageLevel.Log, [].slice.call(arguments)) 
+
 //-----------------------------------------------------------------------------
 method debug
-    Weinre.notImplemented(arguments.callee.signature)
+    this._generic(MessageLevel.Debug, [].slice.call(arguments)) 
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method error
-    Weinre.notImplemented(arguments.callee.signature)
+    this._generic(MessageLevel.Error, [].slice.call(arguments)) 
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method info
-    Weinre.notImplemented(arguments.callee.signature)
+    this._generic(MessageLevel.Log, [].slice.call(arguments)) 
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method warn
-    Weinre.notImplemented(arguments.callee.signature)
+    this._generic(MessageLevel.Warning, [].slice.call(arguments)) 
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method dir
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method dirxml
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method trace
     Weinre.notImplemented(arguments.callee.signature)
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method assert(condition)
     Weinre.notImplemented(arguments.callee.signature)
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method count
     Weinre.notImplemented(arguments.callee.signature)
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-method markTimeline
-    Weinre.notImplemented(arguments.callee.signature)
+method markTimeline(message)
+    Timeline.addRecord_Mark(message)
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method lastWMLErrorMessage
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method profile(title)
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method profileEnd(title)
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method time(title)
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method timeEnd(title)
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method group
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method groupCollapsed
     Weinre.notImplemented(arguments.callee.signature)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method groupEnd
     Weinre.notImplemented(arguments.callee.signature)
diff --git a/weinre.web/modules/weinre/target/ElementHighlighter.scoop b/weinre.web/modules/weinre/target/ElementHighlighter.scoop
index 49654f7..d74cb4f 100644
--- a/weinre.web/modules/weinre/target/ElementHighlighter.scoop
+++ b/weinre.web/modules/weinre/target/ElementHighlighter.scoop
@@ -6,12 +6,10 @@
  * Copyright (c) 2011 IBM Corporation
  */
 
-require ../common/Binding
-require ../common/Weinre
+requireClass ../common/Binding
+requireClass ../common/Weinre
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class ElementHighlighter
     this.boxMargin  = document.createElement("div")
     this.boxBorder  = document.createElement("div")
@@ -57,8 +55,6 @@
     document.body.appendChild(this.boxMargin)
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method on(element)
     if (null == element) return
     if (element.nodeType != Node.ELEMENT_NODE) return
@@ -67,20 +63,14 @@
     this.boxMargin.style.display = "block"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method off
     this.boxMargin.style.display = "none"
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 getter element
     return this.boxMargin
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method calculateMetrics(element)
 
     var metrics = getMetrics(element)
@@ -105,10 +95,6 @@
     this.boxContent.style.bottom = metrics.paddingBottom + "px"
     this.boxContent.style.right  = metrics.paddingRight  + "px"
     
-    
-    
-//-----------------------------------------------------------------------------
-// 
 //-----------------------------------------------------------------------------
 function getMetrics(element)
     var result = {}
@@ -166,7 +152,5 @@
     return result
     
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 function fromPx(string) 
     return parseInt(string.replace(/px$/,""))
diff --git a/weinre.web/modules/weinre/target/InjectedScriptHostImpl.scoop b/weinre.web/modules/weinre/target/InjectedScriptHostImpl.scoop
index 85d82ec..48cf458 100644
--- a/weinre.web/modules/weinre/target/InjectedScriptHostImpl.scoop
+++ b/weinre.web/modules/weinre/target/InjectedScriptHostImpl.scoop
@@ -6,85 +6,40 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Weinre
+requireClass ../common/Weinre
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class InjectedScriptHostImpl
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method clearConsoleMessages(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method copyText(/*string*/ text, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method nodeForId(/*int*/ nodeId, callback)
     return Weinre.nodeStore.getNode(nodeId)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method pushNodePathToFrontend(/*any*/ node, /*boolean*/ withChildren, /*boolean*/ selectInUI, callback)
     // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
+    var nodeId = Weinre.nodeStore.getNodeId(node)
+    var children = Weinre.nodeStore.serializeNode(node, 1)
+    Weinre.wi.DOMNotify.setChildNodes(nodeId, children)
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method inspectedNode(/*int*/ num, callback)
     // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
+    var nodeId = Weinre.nodeStore.getInspectedNode(num)
+    return nodeId
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method currentCallFrame(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method selectDatabase(/*any*/ database, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method selectDOMStorage(/*any*/ storage, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method didCreateWorker(/*int*/ id, /*string*/ url, /*boolean*/ isFakeWorker, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method didDestroyWorker(/*int*/ id, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method nextWorkerId(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
+method internalConstructorName(object)
+    var ctor = object.constructor
+    
+    return ctor.fullClassName || ctor.displayName || ctor.name || "Object"
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/target/InspectorBackendImpl.scoop b/weinre.web/modules/weinre/target/InspectorBackendImpl.scoop
deleted file mode 100644
index 1e10550..0000000
--- a/weinre.web/modules/weinre/target/InspectorBackendImpl.scoop
+++ /dev/null
@@ -1,694 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class InspectorBackendImpl
-    this.inspectedNodes = []
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method populateScriptObjects(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getSettings(callback)
-    // callback: function(/*any*/ settings)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getInspectorState(callback)
-    // callback: function(/*any*/ state)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method storeLastActivePanel(/*string*/ panelName, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method saveApplicationSettings(/*string*/ settings, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method saveSessionSettings(/*string*/ settings, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setSearchingForNode(/*boolean*/ enabled, callback)
-    // callback: function(/*boolean*/ newState)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setMonitoringXHREnabled(/*boolean*/ enable, callback)
-    // callback: function(/*boolean*/ newState)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setResourceTrackingEnabled(/*boolean*/ enabled, /*boolean*/ always, callback)
-    // callback: function(/*boolean*/ newState)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getResourceContent(/*int*/ identifier, /*boolean*/ encode, callback)
-    // callback: function(/*string*/ content)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method reloadPage(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method startTimelineProfiler(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stopTimelineProfiler(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method cachedResources(callback)
-    // callback: function(/*any[]*/ resources)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method resourceContent(/*int*/ frameID, /*string*/ url, callback)
-    // callback: function(/*string*/ content)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method enableDebugger(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method disableDebugger(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setBreakpoint(/*string*/ sourceID, /*int*/ lineNumber, /*boolean*/ enabled, /*string*/ condition, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeBreakpoint(/*string*/ sourceID, /*int*/ lineNumber, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method activateBreakpoints(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method deactivateBreakpoints(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method pause(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method resume(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stepOverStatement(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stepIntoStatement(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stepOutOfFunction(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setPauseOnExceptionsState(/*int*/ pauseOnExceptionsState, callback)
-    // callback: function(/*int*/ newState)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method editScriptSource(/*string*/ sourceID, /*string*/ newContent, callback)
-    // callback: function(/*boolean*/ success, /*any*/ newCallFrames)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getScriptSource(/*string*/ sourceID, callback)
-    // callback: function(/*string*/ scriptSource)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setNativeBreakpoint(/*any*/ breakpoint, callback)
-    // callback: function(/*string*/ breakpointId)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeNativeBreakpoint(/*string*/ breakpointId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method enableProfiler(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method disableProfiler(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method startProfiling(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stopProfiling(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getProfileHeaders(callback)
-    // callback: function(/*any[]*/ headers)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getProfile(/*string*/ type, /*int*/ uid, callback)
-    // callback: function(/*any*/ profile)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeProfile(/*string*/ type, /*int*/ uid, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method clearProfiles(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method takeHeapSnapshot(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setInjectedScriptSource(/*string*/ scriptSource, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method dispatchOnInjectedScript(/*int*/ injectedScriptId, /*string*/ methodName, /*string*/ arguments, callback)
-    var func = Weinre.injectedScript[methodName]
-    if (null == func) {
-          Weinre.notImplemented("Weinre.injectedScript. " + methodName + "()")
-    }
-
-    var isException = false
-    try {
-        var result = func.apply(Weinre.injectedScript, JSON.parse(arguments))
-    }
-    catch(e) {
-        result = e
-        isException = true
-    }
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result, isException])
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method addScriptToEvaluateOnLoad(/*string*/ scriptSource, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeAllScriptsToEvaluateOnLoad(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getChildNodes(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-    
-    var children = Weinre.nodeStore.serializeNodeChildren(node, 1)
-    WebInspector.setChildNodes(nodeId, children)
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setAttribute(/*int*/ elementId, /*string*/ name, /*string*/ value, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeAttribute(/*int*/ elementId, /*string*/ name, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setTextNodeValue(/*int*/ nodeId, /*string*/ value, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getEventListenersForNode(/*int*/ nodeId, callback)
-    // callback: function(/*int*/ outNodeId)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method copyNode(/*int*/ nodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeNode(/*int*/ nodeId, callback)
-    // callback: function(/*int*/ outNodeId)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method changeTagName(/*int*/ nodeId, /*string*/ newTagName, callback)
-    // callback: function(/*int*/ outNodeId)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getOuterHTML(/*int*/ nodeId, callback)
-    // callback: function(/*string*/ outerHTML)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setOuterHTML(/*int*/ nodeId, /*string*/ outerHTML, callback)
-    // callback: function(/*int*/ outNodeId)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method addInspectedNode(/*int*/ nodeId, callback)
-    this.inspectedNodes.unshift(nodeId)
-    if (this.inspectedNodes.length > 5) {
-        this.inspectedNodes = this.inspectedNodes.slice(0,5)
-    }
-        
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method performSearch(/*string*/ query, /*boolean*/ runSynchronously, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method searchCanceled(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method pushNodeByPathToFrontend(/*string*/ path, callback)
-    // callback: function(/*int*/ nodeId)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setConsoleMessagesEnabled(/*boolean*/ enabled, callback)
-    // callback: function(/*boolean*/ newState)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method clearConsoleMessages(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method highlightDOMNode(/*int*/ nodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method hideDOMNodeHighlight(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method openInInspectedWindow(/*string*/ url, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getStyles(/*int*/ nodeId, /*boolean*/ authOnly, callback)
-    
-    var styles = {
-        "inlineStyle": {},
-        "computedStyle": {},
-        "matchedCSSRules": [],
-        "styleAttributes": {},
-        "pseudoElements": []
-//      "parent": {}
-    }
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [styles])
-    }
-
-    /*
-    Element* element = static_cast<Element*>(node);
-    RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = computedStyle(node, true); // Support the viewing of :visited information in computed style.
-
-    RefPtr<InspectorObject> result = InspectorObject::create();
-    if (element->style())
-        result->setObject("inlineStyle", buildObjectForStyle(element->style(), true));
-    result->setObject("computedStyle", buildObjectForStyle(computedStyleInfo.get(), false));
-
-    CSSStyleSelector* selector = element->ownerDocument()->styleSelector();
-    RefPtr<CSSRuleList> matchedRules = selector->styleRulesForElement(element, authorOnly, true);
-    result->setArray("matchedCSSRules", buildArrayForCSSRules(node->ownerDocument(), matchedRules.get()));
-
-    result->setObject("styleAttributes", buildObjectForAttributeStyles(element));
-    result->setArray("pseudoElements", buildArrayForPseudoElements(element, authorOnly));
-
-    RefPtr<InspectorObject> currentStyle = result;
-    Element* parentElement = element->parentElement();
-    while (parentElement) {
-        RefPtr<InspectorObject> parentStyle = InspectorObject::create();
-        currentStyle->setObject("parent", parentStyle);
-        if (parentElement->style() && parentElement->style()->length())
-            parentStyle->setObject("inlineStyle", buildObjectForStyle(parentElement->style(), true));
-
-        CSSStyleSelector* parentSelector = parentElement->ownerDocument()->styleSelector();
-        RefPtr<CSSRuleList> parentMatchedRules = parentSelector->styleRulesForElement(parentElement, authorOnly, true);
-        parentStyle->setArray("matchedCSSRules", buildArrayForCSSRules(parentElement->ownerDocument(), parentMatchedRules.get()));
-
-        parentElement = parentElement->parentElement();
-        currentStyle = parentStyle;
-    }
-    *styles = result.release();
-    */
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getAllStyles(callback)
-    // callback: function(/*any[]*/ styles)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getInlineStyle(/*int*/ nodeId, callback)
-    // callback: function(/*any*/ style)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getComputedStyle(/*int*/ nodeId, callback)
-    // callback: function(/*any*/ style)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getStyleSheet(/*int*/ styleSheetId, callback)
-    // callback: function(/*any*/ styleSheet)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getStyleSourceData(/*int*/ styleSheetId, callback)
-    // callback: function(/*any*/ styleSourceData)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method applyStyleText(/*int*/ styleId, /*string*/ styleText, /*string*/ propertyName, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setStyleText(/*int*/ styleId, /*string*/ styleText, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setStyleProperty(/*int*/ styleId, /*string*/ name, /*string*/ value, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method toggleStyleEnabled(/*int*/ styleId, /*string*/ propertyName, /*boolean*/ disabled, callback)
-    // callback: function(/*any*/ style)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setRuleSelector(/*int*/ ruleId, /*string*/ selector, /*int*/ selectedNodeId, callback)
-    // callback: function(/*any*/ rule)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method addRule(/*string*/ selector, /*int*/ selectedNodeId, callback)
-    // callback: function(/*any*/ rule)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getSupportedCSSProperties(callback)
-    // callback: function(/*any[]*/ cssProperties)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getCookies(callback)
-    // callback: function(/*any[]*/ cookies)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method deleteCookie(/*string*/ cookieName, /*string*/ domain, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getApplicationCaches(callback)
-    // callback: function(/*any*/ applicationCaches)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method releaseWrapperObjectGroup(/*int*/ injectedScriptId, /*string*/ objectGroup, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method didEvaluateForTestInFrontend(/*int*/ testCallId, /*string*/ jsonResult, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getDatabaseTableNames(/*int*/ databaseId, callback)
-    // callback: function(/*any[]*/ tableNames)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method executeSQL(/*int*/ databaseId, /*string*/ query, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getDOMStorageEntries(/*int*/ storageId, callback)
-    // callback: function(/*any[]*/ entries)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setDOMStorageItem(/*int*/ storageId, /*string*/ key, /*string*/ value, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeDOMStorageItem(/*int*/ storageId, /*string*/ key, callback)
-    // callback: function(/*boolean*/ success)
-    Weinre.notImplemented(arguments.callee.signature)
-
diff --git a/weinre.web/modules/weinre/target/NodeStore.scoop b/weinre.web/modules/weinre/target/NodeStore.scoop
index 40ef0c9..2ddd83a 100644
--- a/weinre.web/modules/weinre/target/NodeStore.scoop
+++ b/weinre.web/modules/weinre/target/NodeStore.scoop
@@ -7,22 +7,29 @@
  */
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class NodeStore
-    this.__nodeMap     = {}
-    this.__nodeDataMap = {}
-    this.__nextId      = 0
+    this.__nodeMap      = {}
+    this.__nodeDataMap  = {}
+    this.__nextId       = 0
+    this.inspectedNodes = []
+
 
 //-----------------------------------------------------------------------------
-//
+method addInspectedNode(nodeId)
+    this.inspectedNodes.unshift(nodeId)
+    if (this.inspectedNodes.length > 5) {
+        this.inspectedNodes = this.inspectedNodes.slice(0,5)
+    }
+
+//-----------------------------------------------------------------------------
+method getInspectedNode(index)
+    return this.inspectedNodes[index]
+
 //-----------------------------------------------------------------------------
 method getNode(nodeId)
     return this.__nodeMap[nodeId]
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getNodeId(node)
     if (node.__weinre_id) { 
         return node.__weinre_id
@@ -34,22 +41,16 @@
     return node.__weinre_id
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method getNodeData(nodeId, depth)
     return this.serializeNode(this.getNode(nodeId), depth)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method nextNodeId()
     return "" + (++this.__nextId)
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method serializeNode(node, depth)
-    var nodeName  = null
+    var nodeName  = ""
     var nodeValue = null
     var localName = null
     var id = this.getNodeId(node) 
@@ -115,8 +116,6 @@
     return nodeData
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method serializeNodeChildren(node, depth)
     var result   = []
     var childIds = this.childNodeIds(node)
@@ -139,14 +138,10 @@
     return result
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method childNodeCount(node)
     return this.childNodeIds(node).length
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method childNodeIds(node)
     var ids = []
     
@@ -158,8 +153,6 @@
     return ids
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method isToBeSkipped(node)
     if (!node) return true
     if (node.__weinreHighlighter) return true 
diff --git a/weinre.web/modules/weinre/target/Target.scoop b/weinre.web/modules/weinre/target/Target.scoop
index 3b5a6c7..73d8c00 100644
--- a/weinre.web/modules/weinre/target/Target.scoop
+++ b/weinre.web/modules/weinre/target/Target.scoop
@@ -6,43 +6,42 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Binding
-require ../common/Callback
-require ../common/Socket
-require ../common/Weinre
+requireClass ../common/Native
 
-require ./NodeStore
-require ./CSSStore
-require ./ElementHighlighter
-require ./InjectedScriptHostImpl
-require ./WebInspectorApplicationCacheHandlerImpl
-require ./WebInspectorBackendHandlerImpl
-require ./WebInspectorControllerHandlerImpl
-require ./WebInspectorDOMHandlerImpl   
-require ./WebInspectorDebugHandlerImpl
-require ./WebInspectorProfilerHandlerImpl
-require ./WebInspectorResourceHandlerImpl
-require ./WeinreTargetEventsImpl
+requireClass ../common/Ex
+requireClass ../common/Binding
+requireClass ../common/Callback
+requireClass ../common/MessageDispatcher
+requireClass ../common/Weinre
 
-//-----------------------------------------------------------------------------
-// 
+requireClass ./NodeStore
+requireClass ./CSSStore
+requireClass ./ElementHighlighter
+requireClass ./InjectedScriptHostImpl
+
+requireClass ./WeinreTargetEventsImpl
+
+requireClass ./WiConsoleImpl
+requireClass ./WiCSSImpl
+requireClass ./WiDatabaseImpl
+requireClass ./WiDOMImpl
+requireClass ./WiDOMStorageImpl
+requireClass ./WiInspectorImpl
+requireClass ./WiRuntimeImpl
+
 //-----------------------------------------------------------------------------
 class Target
-    this.initialize()
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 static method main
     Weinre.target = new Target()
+    Weinre.target.initialize()
     
     Weinre.addCSSProperties = function addCSSProperties(properties) {
         CSSStore.addCSSProperties(properties)
     }
     
 //------------------------------------------------------------------------------
-//
-//------------------------------------------------------------------------------
 method setWeinreServerURLFromScriptSrc()
     if (window.WeinreServerURL) return
     
@@ -66,11 +65,9 @@
     
     var message = "unable to calculate the weinre server url; explicity set the variable window.WeinreServerURL instead" 
     alert(message)
-    throw new Error(message)
+    throw new Ex(arguments, message)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method initialize()
     this.setWeinreServerURLFromScriptSrc()
     
@@ -83,46 +80,60 @@
     
     window.addEventListener("load", Binding(this, "onLoaded"), false)
 
-    var webSocket = new Socket(window.WeinreServerURL + "ws/target")
-    Weinre.webSocket = webSocket
+    var messageDispatcher = new MessageDispatcher(window.WeinreServerURL + "ws/target")
+    Weinre.messageDispatcher = messageDispatcher
 
-    Weinre.WebInspectorApplicationCacheHandler = new WebInspectorApplicationCacheHandlerImpl()
-    Weinre.WebInspectorBackendHandler          = new WebInspectorBackendHandlerImpl()  
-    Weinre.WebInspectorControllerHandler       = new WebInspectorControllerHandlerImpl()
-    Weinre.WebInspectorDOMHandler              = new WebInspectorDOMHandlerImpl()        
-    Weinre.WebInspectorDebugHandler            = new WebInspectorDebugHandlerImpl()
-    Weinre.WebInspectorProfilerHandler         = new WebInspectorProfilerHandlerImpl()
-    Weinre.WebInspectorResourceHandler         = new WebInspectorResourceHandlerImpl()
-
-    webSocket.registerInterface("WebInspectorApplicationCacheHandler", Weinre.WebInspectorApplicationCacheHandler, true)
-    webSocket.registerInterface("WebInspectorBackendHandler",          Weinre.WebInspectorBackendHandler,          true)
-    webSocket.registerInterface("WebInspectorControllerHandler",       Weinre.WebInspectorControllerHandler,       true)
-    webSocket.registerInterface("WebInspectorDOMHandler",              Weinre.WebInspectorDOMHandler,              true)
-    webSocket.registerInterface("WebInspectorDebugHandler",            Weinre.WebInspectorDebugHandler,            true)
-    webSocket.registerInterface("WebInspectorProfilerHandler",         Weinre.WebInspectorProfilerHandler,         true)
-    webSocket.registerInterface("WebInspectorResourceHandler",         Weinre.WebInspectorResourceHandler,         true)
+    Weinre.wi = {}
     
-    webSocket.registerInterface("WeinreTargetEvents", new WeinreTargetEventsImpl(), true)
+    Weinre.wi.Console          = new WiConsoleImpl()
+    Weinre.wi.CSS              = new WiCSSImpl()
+    Weinre.wi.Database         = new WiDatabaseImpl()
+    Weinre.wi.DOM              = new WiDOMImpl()
+    Weinre.wi.DOMStorage       = new WiDOMStorageImpl()
+    Weinre.wi.Inspector        = new WiInspectorImpl()
+    Weinre.wi.Runtime          = new WiRuntimeImpl()
+    
+    messageDispatcher.registerInterface("Console",          Weinre.wi.Console          , false)
+    messageDispatcher.registerInterface("CSS",              Weinre.wi.CSS              , false)
+    messageDispatcher.registerInterface("Database",         Weinre.wi.Database         , false)
+    messageDispatcher.registerInterface("DOM",              Weinre.wi.DOM              , false)
+    messageDispatcher.registerInterface("DOMStorage",       Weinre.wi.DOMStorage       , false)
+    messageDispatcher.registerInterface("Inspector",        Weinre.wi.Inspector        , false)
+    messageDispatcher.registerInterface("Runtime",          Weinre.wi.Runtime          , false)
+    
+    messageDispatcher.registerInterface("WeinreTargetEvents", new WeinreTargetEventsImpl(), true)
 
-    Weinre.WeinreTargetCommands  = webSocket.createProxy("WeinreTargetCommands")
-    window.WebInspector          = webSocket.createProxy("WebInspector")
+    Weinre.wi.ApplicationCacheNotify = messageDispatcher.createProxy("ApplicationCacheNotify")
+    Weinre.wi.ConsoleNotify          = messageDispatcher.createProxy("ConsoleNotify")
+    Weinre.wi.DOMNotify              = messageDispatcher.createProxy("DOMNotify")
+    Weinre.wi.DOMStorageNotify       = messageDispatcher.createProxy("DOMStorageNotify")
+    Weinre.wi.DatabaseNotify         = messageDispatcher.createProxy("DatabaseNotify")
+    Weinre.wi.InspectorNotify        = messageDispatcher.createProxy("InspectorNotify")
+    Weinre.wi.TimelineNotify         = messageDispatcher.createProxy("TimelineNotify")
+    
+    Weinre.WeinreTargetCommands  = messageDispatcher.createProxy("WeinreTargetCommands")
 
-//  Weinre.Socket.verbose(true)
-    webSocket.open()
-    webSocket._socket.addEventListener("open", Binding(this, this.cb_webSocketOpened))
+    messageDispatcher.getWebSocket().addEventListener("open", Binding(this, this.cb_webSocketOpened))
     
     Weinre.nodeStore = new NodeStore()
     Weinre.cssStore  = new CSSStore()
-
+    
+    window.addEventListener("error", function(e) {Target.handleError(e)}, false)
+    
+    
 //-----------------------------------------------------------------------------
-// 
+static method handleError(event)
+    var filename = event.filename || "[unknown filename]"
+    var lineno   = event.lineno   || "[unknown lineno]"
+    var message  = event.message  || "[unknown message]"
+
+    Weinre.logError("error occurred: " + filename + ":" + lineno + ": " + message)
+
 //-----------------------------------------------------------------------------
 method cb_webSocketOpened()
     Weinre.WeinreTargetCommands.registerTarget(window.location.href, Binding(this, this.cb_registerTarget))
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method cb_registerTarget(targetId)
     Weinre.targetId    = targetId
     Weinre.connectorId = targetId
@@ -130,17 +141,13 @@
     Callback.setConnectorId(targetId)
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method onLoaded()
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 method setDocument()
     Weinre.elementHighlighter = new ElementHighlighter()
     
     var nodeId = Weinre.nodeStore.getNodeId(document)
     var nodeData = Weinre.nodeStore.getNodeData(nodeId, 2)
 
-    WebInspector.setDocument(nodeData)
+    Weinre.wi.DOMNotify.setDocument(nodeData)
diff --git a/weinre.web/modules/weinre/target/Timeline.scoop b/weinre.web/modules/weinre/target/Timeline.scoop
new file mode 100644
index 0000000..4614dc6
--- /dev/null
+++ b/weinre.web/modules/weinre/target/Timeline.scoop
@@ -0,0 +1,326 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Ex
+requireClass ../common/Weinre
+requireClass ../common/IDGenerator
+requireClass ../common/StackTrace
+
+requireClass ../common/Native
+
+//-----------------------------------------------------------------------------
+class Timeline
+
+//-----------------------------------------------------------------------------
+static method start
+    Running = true
+
+//-----------------------------------------------------------------------------
+static method stop
+    Running = false
+
+//-----------------------------------------------------------------------------
+static method isRunning
+    return Running
+
+//-----------------------------------------------------------------------------
+static method addRecord_Mark(message)
+    if (!Timeline.isRunning()) return
+    
+    var record = {}
+
+    record.type      = TimelineRecordType.Mark
+    record.category  = { name: "scripting" }
+    record.startTime = Date.now()
+    record.data      = { message: message }
+    
+    addStackTrace(record, 3)
+    
+    Weinre.wi.TimelineNotify.addRecordToTimeline(record)
+
+//-----------------------------------------------------------------------------
+static method addRecord_EventDispatch(event, name, category)
+    if (!Timeline.isRunning()) return
+    
+    if (!category) category = "scripting"
+    var record = {}
+
+    record.type      = TimelineRecordType.EventDispatch
+    record.category  = { name: category }
+    record.startTime = Date.now()
+    record.data      = { type: event.type }
+    
+    Weinre.wi.TimelineNotify.addRecordToTimeline(record)
+    
+//-----------------------------------------------------------------------------
+static method addRecord_TimerInstall(id, timeout, singleShot)
+    if (!Timeline.isRunning()) return
+    
+    var record = {}
+
+    record.type      = TimelineRecordType.TimerInstall
+    record.category  = { name: "scripting" }
+    record.startTime = Date.now()
+    record.data      = { timerId: id, timeout: timeout, singleShot: singleShot }
+    
+    addStackTrace(record, 4)
+    
+    Weinre.wi.TimelineNotify.addRecordToTimeline(record)
+
+//-----------------------------------------------------------------------------
+static method addRecord_TimerRemove(id, timeout, singleShot)
+    if (!Timeline.isRunning()) return
+
+    var record = {}
+
+    record.type      = TimelineRecordType.TimerRemove
+    record.category  = { name: "scripting" }
+    record.startTime = Date.now()
+    record.data      = { timerId: id, timeout: timeout, singleShot: singleShot }
+
+    addStackTrace(record, 4)
+    
+    Weinre.wi.TimelineNotify.addRecordToTimeline(record)
+
+//-----------------------------------------------------------------------------
+static method addRecord_TimerFire(id, timeout, singleShot)
+    if (!Timeline.isRunning()) return
+
+    var record = {}
+
+    record.type      = TimelineRecordType.TimerFire
+    record.category  = { name: "scripting" }
+    record.startTime = Date.now()
+    record.data      = { timerId: id, timeout: timeout, singleShot: singleShot }
+    
+    Weinre.wi.TimelineNotify.addRecordToTimeline(record)
+
+//-----------------------------------------------------------------------------
+static method addRecord_XHRReadyStateChange(method, url, id, xhr)
+    if (!Timeline.isRunning()) return
+
+    var record
+    
+    if (xhr.readyState == XMLHttpRequest.OPENED) {
+        record = {
+            type:      TimelineRecordType.ResourceSendRequest,
+            category:  { name: "loading" },
+            startTime: Date.now(),
+            data: { 
+                identifier:     id,
+                url:            url,
+                requestMethod:  method
+            }
+        }
+    }
+    
+    else if (xhr.readyState == XMLHttpRequest.DONE) {
+        record = {
+            type:      TimelineRecordType.ResourceReceiveResponse,
+            category:  { name: "loading" },
+            startTime: Date.now(),
+            data: {
+                identifier:            id,
+                statusCode:            xhr.status,
+                mimeType:              xhr.getResponseHeader("Content-Type"),
+                expectedContentLength: xhr.getResponseHeader("Content-Length"),
+                url:                   url
+            }
+        }
+    }
+    
+    else 
+        return
+    
+    Weinre.wi.TimelineNotify.addRecordToTimeline(record)
+
+//-----------------------------------------------------------------------------
+static method installGlobalListeners
+    if (applicationCache) {
+        applicationCache.addEventListener("checking",    function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.checking",    "loading")}, false)
+        applicationCache.addEventListener("error",       function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.error",       "loading")}, false)
+        applicationCache.addEventListener("noupdate",    function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.noupdate",    "loading")}, false)
+        applicationCache.addEventListener("downloading", function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.downloading", "loading")}, false)
+        applicationCache.addEventListener("progress",    function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.progress",    "loading")}, false)
+        applicationCache.addEventListener("updateready", function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.updateready", "loading")}, false)
+        applicationCache.addEventListener("cached",      function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.cached",      "loading")}, false)
+        applicationCache.addEventListener("obsolete",    function(e) {Timeline.addRecord_EventDispatch(e, "applicationCache.obsolete",    "loading")}, false)
+    }
+    
+    // window.addEventListener("deviceorientation", function(e) {Timeline.addRecord_EventDispatch("window.deviceorientation")}, false)
+    window.addEventListener("error",             function(e) {Timeline.addRecord_EventDispatch(e, "window.error")},             false)
+    window.addEventListener("hashchange",        function(e) {Timeline.addRecord_EventDispatch(e, "window.hashchange")},        false)
+    window.addEventListener("message",           function(e) {Timeline.addRecord_EventDispatch(e, "window.message")},           false)
+    window.addEventListener("offline",           function(e) {Timeline.addRecord_EventDispatch(e, "window.offline")},           false)
+    window.addEventListener("online",            function(e) {Timeline.addRecord_EventDispatch(e, "window.online")},            false)
+    window.addEventListener("scroll",            function(e) {Timeline.addRecord_EventDispatch(e, "window.scroll")},            false)
+    
+//-----------------------------------------------------------------------------
+static method installFunctionWrappers
+    window.clearInterval  = wrapped_clearInterval
+    window.clearTimeout   = wrapped_clearTimeout
+    window.setTimeout     = wrapped_setTimeout
+    window.setInterval    = wrapped_setInterval
+
+    window.XMLHttpRequest.prototype.open = wrapped_XMLHttpRequest_open
+    window.XMLHttpRequest                = wrapped_XMLHttpRequest
+
+//-----------------------------------------------------------------------------
+function addStackTrace(record, skip)
+    if (!skip) skip = 1
+    
+    var trace = new StackTrace(arguments).trace
+    
+    record.stackTrace = []
+    
+    for (var i=skip; i<trace.length; i++) {
+        record.stackTrace.push({
+            functionName: trace[i],
+            scriptName:   "",
+            lineNumber:   ""
+        })
+    }
+    
+//-----------------------------------------------------------------------------
+function wrapped_setInterval(code, interval)
+    var code = instrumentedTimerCode(code, interval, false)
+    var id = Native.setInterval(code, interval)
+    
+    code.__timerId = id
+    
+    addTimer(id, interval, false)
+
+    return id
+
+//-----------------------------------------------------------------------------
+function wrapped_setTimeout(code, delay)
+    var code = instrumentedTimerCode(code, delay, true)
+    var id   = Native.setTimeout(code, delay)
+
+    code.__timerId = id
+    
+    addTimer(id, delay, true)
+
+    return id
+
+//-----------------------------------------------------------------------------
+function wrapped_clearInterval(id)
+    var result = Native.clearInterval(id)
+    
+    removeTimer(id, false)
+    return result
+
+//-----------------------------------------------------------------------------
+function wrapped_clearTimeout(id)
+    var result = Native.clearTimeout(id)
+    
+    removeTimer(id, true)
+    return result
+
+//-----------------------------------------------------------------------------
+function addTimer(id, timeout, singleShot)
+    var timerSet = singleShot ? TimerTimeouts : TimerIntervals
+    
+    timerSet[id] = {
+         id:          id,
+         timeout:     timeout,
+         singleShot: singleShot
+    }
+    
+    Timeline.addRecord_TimerInstall(id, timeout, singleShot)
+    
+//-----------------------------------------------------------------------------
+function removeTimer(id, singleShot)
+    var timerSet = singleShot ? TimerTimeouts : TimerIntervals
+    var timer = timerSet[id]
+    
+    if (!timer) return
+    
+    Timeline.addRecord_TimerRemove(id, timer.timeout, singleShot)
+    
+    delete timerSet[id]
+    
+//-----------------------------------------------------------------------------
+function instrumentedTimerCode(code, timeout, singleShot)
+    if (typeof(code) != "function") return code
+    
+    var instrumentedCode = function() {
+        var result = code()
+        var id     = arguments.callee.__timerId
+
+        Timeline.addRecord_TimerFire(id, timeout, singleShot)
+
+        return result
+    }
+    
+    return instrumentedCode 
+
+//-----------------------------------------------------------------------------
+function wrapped_XMLHttpRequest
+    var xhr = new Native.XMLHttpRequest()
+    xhr.__weinre_id = IDGenerator.next()
+    xhr.addEventListener("readystatechange", getXhrEventHandler(xhr), false)
+    return xhr
+
+init
+    wrapped_XMLHttpRequest.UNSENT           = 0
+    wrapped_XMLHttpRequest.OPENED           = 1
+    wrapped_XMLHttpRequest.HEADERS_RECEIVED = 2
+    wrapped_XMLHttpRequest.LOADING          = 3
+    wrapped_XMLHttpRequest.DONE             = 4    
+
+//-----------------------------------------------------------------------------
+function wrapped_XMLHttpRequest_open()
+    var xhr = this
+    xhr.__weinre_method  = arguments[0]
+    xhr.__weinre_url     = arguments[1]
+    
+    var result = Native.XMLHttpRequest_open.apply(xhr, [].slice.call(arguments))
+    return result
+
+    
+//-----------------------------------------------------------------------------
+function getXhrEventHandler(xhr)
+    return function(event) {
+        Timeline.addRecord_XHRReadyStateChange(xhr.__weinre_method, xhr.__weinre_url, xhr.__weinre_id, xhr)
+    }
+    
+//-----------------------------------------------------------------------------
+init 
+    var Running = false
+    
+    var TimerTimeouts  = {}
+    var TimerIntervals = {}
+
+    var TimelineRecordType = {
+            EventDispatch:            0,
+            Layout:                   1,
+            RecalculateStyles:        2,
+            Paint:                    3,
+            ParseHTML:                4,
+            TimerInstall:             5,
+            TimerRemove:              6,
+            TimerFire:                7,
+            XHRReadyStateChange:      8,
+            XHRLoad:                  9,
+            EvaluateScript:          10,
+            Mark:                    11,
+            ResourceSendRequest:     12,
+            ResourceReceiveResponse: 13,
+            ResourceFinish:          14,
+            FunctionCall:            15,
+            ReceiveResourceData:     16,
+            GCEvent:                 17,
+            MarkDOMContent:          18,
+            MarkLoad:                19,
+            ScheduleResourceRequest: 20
+    }
+
+    Timeline.installGlobalListeners()
+    Timeline.installFunctionWrappers()
+    
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/target/WebInspectorApplicationCacheHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorApplicationCacheHandlerImpl.scoop
deleted file mode 100644
index d44ee6c..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorApplicationCacheHandlerImpl.scoop
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorApplicationCacheHandlerImpl
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getApplicationCaches(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
diff --git a/weinre.web/modules/weinre/target/WebInspectorBackendHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorBackendHandlerImpl.scoop
deleted file mode 100644
index c4ca13c..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorBackendHandlerImpl.scoop
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorBackendHandlerImpl
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method enableDebugger(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented('WebInspectorBackendHandler::enableDebugger()')
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setInjectedScriptSource(/*string*/ scriptSource, callback)
-    // callback: function()
-    Weinre.notImplemented('WebInspectorBackendHandler::setInjectedScriptSource()')
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method dispatchOnInjectedScript(/*int*/ injectedScriptId, /*string*/ methodName, /*string*/ arguments, callback)
-    var func = Weinre.injectedScript[methodName]
-    if (null == func) {
-          console.log(arguments.callee.signature + ": no method '" + methodName + "' on injectedScript")
-    }
-
-    var isException = false
-    try {
-        var result = func.apply(Weinre.injectedScript, JSON.parse(arguments))
-    }
-    catch(e) {
-        result = e
-        isException = true
-    }
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result, isException])
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method releaseWrapperObjectGroup(/*int*/ injectedScriptId, /*string*/ objectGroup, callback)
-    // callback: function()
-    Weinre.notImplemented('WebInspectorBackendHandler::releaseWrapperObjectGroup()')
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getDatabaseTableNames(/*int*/ databaseId, callback)
-    // callback: function()
-    Weinre.notImplemented('WebInspectorBackendHandler::getDatabaseTableNames()')
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method executeSQL(/*int*/ databaseId, /*string*/ query, callback)
-    // callback: function()
-    Weinre.notImplemented('WebInspectorBackendHandler::executeSQL() not implemented')
-
-
diff --git a/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop
deleted file mode 100644
index 61a17a9..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorControllerHandlerImpl.scoop
+++ /dev/null
@@ -1,244 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorControllerHandlerImpl
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method populateScriptObjects(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getSettings(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getInspectorState(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method storeLastActivePanel(/*string*/ panelName, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method saveApplicationSettings(/*string*/ settings, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method saveSessionSettings(/*string*/ settings, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setSearchingForNode(/*boolean*/ enabled, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setMonitoringXHREnabled(/*boolean*/ enable, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setResourceTrackingEnabled(/*boolean*/ enabled, /*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getResourceContent(/*int*/ identifier, /*boolean*/ encode, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method reloadPage(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method startTimelineProfiler(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stopTimelineProfiler(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method disableDebugger(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setNativeBreakpoint(/*any*/ breakpoint, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeNativeBreakpoint(/*string*/ breakpointId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method enableProfiler(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method disableProfiler(/*boolean*/ always, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method addScriptToEvaluateOnLoad(/*string*/ scriptSource, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeAllScriptsToEvaluateOnLoad(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setConsoleMessagesEnabled(/*boolean*/ enabled, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method clearConsoleMessages(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method highlightDOMNode(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-
-    Weinre.elementHighlighter.on(node)
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method hideDOMNodeHighlight(callback)
-    Weinre.elementHighlighter.off()
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method openInInspectedWindow(/*string*/ url, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getCookies(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method deleteCookie(/*string*/ cookieName, /*string*/ domain, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method didEvaluateForTestInFrontend(/*int*/ testCallId, /*string*/ jsonResult, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getDOMStorageEntries(/*int*/ storageId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setDOMStorageItem(/*int*/ storageId, /*string*/ key, /*string*/ value, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeDOMStorageItem(/*int*/ storageId, /*string*/ key, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
diff --git a/weinre.web/modules/weinre/target/WebInspectorDOMHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorDOMHandlerImpl.scoop
deleted file mode 100644
index ac94010..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorDOMHandlerImpl.scoop
+++ /dev/null
@@ -1,330 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorDOMHandlerImpl
-    this.inspectedNodes = []
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getChildNodes(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature  + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-    
-    var children = Weinre.nodeStore.serializeNodeChildren(node, 1)
-    WebInspector.setChildNodes(nodeId, children)
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setAttribute(/*int*/ elementId, /*string*/ name, /*string*/ value, callback)
-    var element = Weinre.nodeStore.getNode(elementId)
-    if (!element) {
-        console.log(arguments.callee.signature + " passed an invalid elementId: " + elementId)
-        return
-    }
-    
-    element.setAttribute(name, value)
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeAttribute(/*int*/ elementId, /*string*/ name, callback)
-    var element = Weinre.nodeStore.getNode(elementId)
-    if (!element) {
-        console.log(arguments.callee.signature + " passed an invalid elementId: " + elementId)
-        return
-    }
-    
-    element.removeAttribute(name)
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setTextNodeValue(/*int*/ nodeId, /*string*/ value, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-    
-    node.nodeValue = value
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getEventListenersForNode(/*int*/ nodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method copyNode(/*int*/ nodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeNode(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-
-    if (!node.parentNode) {
-        console.log(arguments.callee.signature + " passed a parentless node: " + node)
-        return
-    }
-    
-    node.parentNode.removeChild(node)
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method changeTagName(/*int*/ nodeId, /*string*/ newTagName, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getOuterHTML(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-
-    value = node.outerHTML
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [value])
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setOuterHTML(/*int*/ nodeId, /*string*/ outerHTML, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-
-    node.outerHTML = outerHTML
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method addInspectedNode(/*int*/ nodeId, callback)
-    this.inspectedNodes.unshift(nodeId)
-    if (this.inspectedNodes.length > 5) {
-        this.inspectedNodes = this.inspectedNodes.slice(0,5)
-    }
-        
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback)
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method performSearch(/*string*/ query, /*boolean*/ runSynchronously, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method searchCanceled(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method pushNodeByPathToFrontend(/*string*/ path, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getStyles(/*int*/ nodeId, /*boolean*/ authOnly, callback)
-    var result = {}
-    
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-    
-    var result = {
-        inlineStyle:     Weinre.cssStore.getInlineStyle(node),
-        computedStyle:   Weinre.cssStore.getComputedStyle(node),
-        matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(node),
-        styleAttributes: Weinre.cssStore.getStyleAttributes(node),
-        pseudoElements:  Weinre.cssStore.getPseudoElements(node),
-    }
-    
-    var parentNode   = node.parentNode
-    var currentStyle = result
-    
-    while (parentNode) {
-        var parentStyle = {
-            inlineStyle:     Weinre.cssStore.getInlineStyle(parentNode),
-            matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(parentNode),
-        }
-        
-        currentStyle.parent = parentStyle
-        
-        currentStyle = parentStyle
-        parentNode   = parentNode.parentNode
-    }
-    
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getAllStyles(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getInlineStyle(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-
-    var result = Weinre.cssStore.getInlineStyle(node)
-
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getComputedStyle(/*int*/ nodeId, callback)
-    var node = Weinre.nodeStore.getNode(nodeId)
-    if (!node) {
-        console.log(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
-        return
-    }
-
-    var result = Weinre.cssStore.getComputedStyle(node) 
-
-    if (callback) {
-        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
-    }
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getStyleSheet(/*int*/ styleSheetId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getStyleSourceData(/*int*/ styleSheetId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method applyStyleText(/*int*/ styleId, /*string*/ styleText, /*string*/ propertyName, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setStyleText(/*int*/ styleId, /*string*/ styleText, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setStyleProperty(/*int*/ styleId, /*string*/ name, /*string*/ value, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method toggleStyleEnabled(/*int*/ styleId, /*string*/ propertyName, /*boolean*/ disabled, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setRuleSelector(/*int*/ ruleId, /*string*/ selector, /*int*/ selectedNodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method addRule(/*string*/ selector, /*int*/ selectedNodeId, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getSupportedCSSProperties(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
diff --git a/weinre.web/modules/weinre/target/WebInspectorDebugHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorDebugHandlerImpl.scoop
deleted file mode 100644
index b498483..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorDebugHandlerImpl.scoop
+++ /dev/null
@@ -1,99 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorDebugHandlerImpl
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setBreakpoint(/*string*/ sourceID, /*int*/ lineNumber, /*boolean*/ enabled, /*string*/ condition, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeBreakpoint(/*string*/ sourceID, /*int*/ lineNumber, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method activateBreakpoints(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method deactivateBreakpoints(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method pause(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method resume(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stepOverStatement(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stepIntoStatement(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stepOutOfFunction(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method setPauseOnExceptionsState(/*int*/ pauseOnExceptionsState, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method editScriptSource(/*string*/ sourceID, /*string*/ newContent, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getScriptSource(/*string*/ sourceID, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
diff --git a/weinre.web/modules/weinre/target/WebInspectorProfilerHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorProfilerHandlerImpl.scoop
deleted file mode 100644
index ebbd300..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorProfilerHandlerImpl.scoop
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorProfilerHandlerImpl
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method startProfiling(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method stopProfiling(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getProfileHeaders(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method getProfile(/*string*/ type, /*int*/ uid, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method removeProfile(/*string*/ type, /*int*/ uid, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method clearProfiles(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method takeHeapSnapshot(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
diff --git a/weinre.web/modules/weinre/target/WebInspectorResourceHandlerImpl.scoop b/weinre.web/modules/weinre/target/WebInspectorResourceHandlerImpl.scoop
deleted file mode 100644
index f9acb4f..0000000
--- a/weinre.web/modules/weinre/target/WebInspectorResourceHandlerImpl.scoop
+++ /dev/null
@@ -1,30 +0,0 @@
-
-/*
- * weinre is available under *either* the terms of the modified BSD license *or* the
- * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
- * Copyright (c) 2010, 2011 IBM Corporation
- */
-
-require ../common/Weinre
-
-//-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
-class WebInspectorResourceHandlerImpl
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method cachedResources(callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-method resourceContent(/*int*/ frameID, /*string*/ url, callback)
-    // callback: function()
-    Weinre.notImplemented(arguments.callee.signature)
-
-
diff --git a/weinre.web/modules/weinre/target/WeinreTargetEventsImpl.scoop b/weinre.web/modules/weinre/target/WeinreTargetEventsImpl.scoop
index b70d9c5..2a00e04 100644
--- a/weinre.web/modules/weinre/target/WeinreTargetEventsImpl.scoop
+++ b/weinre.web/modules/weinre/target/WeinreTargetEventsImpl.scoop
@@ -6,46 +6,33 @@
  * Copyright (c) 2010, 2011 IBM Corporation
  */
 
-require ../common/Weinre
-require ../common/Callback
+requireClass ../common/Weinre
+requireClass ../common/Callback
 
-require ./Console
+requireClass ./Console
 
 //-----------------------------------------------------------------------------
-// 
-//-----------------------------------------------------------------------------
 class WeinreTargetEventsImpl
 
 //-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
 method connectionCreated(/*string*/ clientId, /*string*/ targetId)
     var message = "weinre: target " + targetId + " connected to client " + clientId
     
-    console.log(message)
+    Weinre.logInfo(message)
     var oldValue = Console.useRemote(true)
     
-    if (!oldValue) {
-        console.log(message)
-    }
-    
-    Weinre.target.setDocument()
+    // Weinre.showNotImplemented()
 
-//-----------------------------------------------------------------------------
-//
+    Weinre.target.setDocument()
+    Weinre.wi.TimelineNotify.timelineProfilerWasStopped()
+
 //-----------------------------------------------------------------------------
 method connectionDestroyed(/*string*/ clientId, /*string*/ targetId)
     var message = "weinre: target " + targetId + " disconnected from client " + clientId
     
-    console.log(message)
+    Weinre.logInfo(message)
     var oldValue = Console.useRemote(false)
     
-    if (oldValue) {
-        console.log(message)
-    }
-
-//-----------------------------------------------------------------------------
-//
 //-----------------------------------------------------------------------------
 method sendCallback(/*int*/ callbackId, /*any*/ result)
     Callback.invoke(callbackId, result)
diff --git a/weinre.web/modules/weinre/target/WiCSSImpl.scoop b/weinre.web/modules/weinre/target/WiCSSImpl.scoop
new file mode 100644
index 0000000..ad4cd05
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiCSSImpl.scoop
@@ -0,0 +1,134 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+
+//-----------------------------------------------------------------------------
+class WiCSSImpl
+
+//-----------------------------------------------------------------------------
+method getStylesForNode(/*int*/ nodeId, callback)
+    var result = {}
+    
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+    
+    var result = {
+        inlineStyle:     Weinre.cssStore.getInlineStyle(node),
+        computedStyle:   Weinre.cssStore.getComputedStyle(node),
+        matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(node),
+        styleAttributes: Weinre.cssStore.getStyleAttributes(node),
+        pseudoElements:  Weinre.cssStore.getPseudoElements(node),
+        inherited:       []
+    }
+    
+    var parentNode   = node.parentNode
+    
+    while (parentNode) {
+        var parentStyle = {
+            inlineStyle:     Weinre.cssStore.getInlineStyle(parentNode),
+            matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(parentNode),
+        }
+        
+        result.inherited.push(parentStyle)
+        parentNode = parentNode.parentNode
+    }
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method getComputedStyleForNode(/*int*/ nodeId, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    var result = Weinre.cssStore.getComputedStyle(node) 
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+
+//-----------------------------------------------------------------------------
+method getInlineStyleForNode(/*int*/ nodeId, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    var result = Weinre.cssStore.getInlineStyle(node)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method getAllStyles(callback)
+    // callback: function(/*any[]*/ styleSheetIds)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method getStyleSheet(/*string*/ styleSheetId, callback)
+    // callback: function(/*any*/ styleSheet)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method getStyleSheetText(/*string*/ styleSheetId, callback)
+    // callback: function(/*string*/ url, /*string*/ text)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method setStyleSheetText(/*string*/ styleSheetId, /*string*/ text, callback)
+    // callback: function(/*boolean*/ success)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method setPropertyText(/*any*/ styleId, /*int*/ propertyIndex, /*string*/ text, /*boolean*/ overwrite, callback)
+    // callback: function(/*any*/ style)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method toggleProperty(/*any*/ styleId, /*int*/ propertyIndex, /*boolean*/ disable, callback)
+    // callback: function(/*any*/ style)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method setRuleSelector(/*any*/ ruleId, /*string*/ selector, callback)
+    // callback: function(/*any*/ rule)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method addRule(/*int*/ contextNodeId, /*string*/ selector, callback)
+    // callback: function(/*any*/ rule)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method getSupportedCSSProperties(callback)
+    return Weinre.getCSSProperties()
+
+
+//-----------------------------------------------------------------------------
+method querySelectorAll(/*int*/ documentId, /*string*/ selector, callback)
+    // callback: function(/*any[]*/ result)
+    Weinre.notImplemented(arguments.callee.signature)
diff --git a/weinre.web/modules/weinre/target/WiConsoleImpl.scoop b/weinre.web/modules/weinre/target/WiConsoleImpl.scoop
new file mode 100644
index 0000000..8b8e6a4
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiConsoleImpl.scoop
@@ -0,0 +1,36 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+
+//-----------------------------------------------------------------------------
+class WiConsoleImpl
+    this.messagesEnabled = true
+
+//-----------------------------------------------------------------------------
+method setConsoleMessagesEnabled(/*boolean*/ enabled, callback)
+    var oldValue = this.messagesEnabled
+    this.messagesEnabled = enabled
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [oldValue])
+    }
+
+//-----------------------------------------------------------------------------
+method clearConsoleMessages(callback)
+    Weinre.wi.ConsoleNotify.consoleMessagesCleared()
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [])
+    }
+
+//-----------------------------------------------------------------------------
+method setMonitoringXHREnabled(/*boolean*/ enabled, callback)
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [])
+    }
diff --git a/weinre.web/modules/weinre/target/WiDOMImpl.scoop b/weinre.web/modules/weinre/target/WiDOMImpl.scoop
new file mode 100644
index 0000000..4e7fd2f
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiDOMImpl.scoop
@@ -0,0 +1,188 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+
+//-----------------------------------------------------------------------------
+class WiDOMImpl
+
+//-----------------------------------------------------------------------------
+method getChildNodes(/*int*/ nodeId, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature  + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    var children = Weinre.nodeStore.serializeNodeChildren(node, 1)
+    Weinre.wi.DOMNotify.setChildNodes(nodeId, children)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method setAttribute(/*int*/ elementId, /*string*/ name, /*string*/ value, callback)
+    var element = Weinre.nodeStore.getNode(elementId)
+    if (!element) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid elementId: " + elementId)
+        return
+    }
+
+    element.setAttribute(name, value)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method removeAttribute(/*int*/ elementId, /*string*/ name, callback)
+    var element = Weinre.nodeStore.getNode(elementId)
+    if (!element) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid elementId: " + elementId)
+        return
+    }
+
+    element.removeAttribute(name)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method setTextNodeValue(/*int*/ nodeId, /*string*/ value, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    node.nodeValue = value
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method getEventListenersForNode(/*int*/ nodeId, callback)
+    // callback: function(/*int*/ outNodeId, /*any[]*/ listenersArray)
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method copyNode(/*int*/ nodeId, callback)
+    // callback: function()
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method removeNode(/*int*/ nodeId, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    if (!node.parentNode) {
+        Weinre.logWarning(arguments.callee.signature + " passed a parentless node: " + node)
+        return
+    }
+
+    node.parentNode.removeChild(node)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method changeTagName(/*int*/ nodeId, /*string*/ newTagName, callback)
+    // callback: function(/*int*/ outNodeId)
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method getOuterHTML(/*int*/ nodeId, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    value = node.outerHTML
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [value])
+    }
+
+//-----------------------------------------------------------------------------
+method setOuterHTML(/*int*/ nodeId, /*string*/ outerHTML, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    node.outerHTML = outerHTML
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method addInspectedNode(/*int*/ nodeId, callback)
+    Weinre.nodeStore.addInspectedNode(nodeId)
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+    
+//-----------------------------------------------------------------------------
+method performSearch(/*string*/ query, /*boolean*/ runSynchronously, callback)
+    // callback: function()
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method searchCanceled(callback)
+    // callback: function()
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method pushNodeByPathToFrontend(/*string*/ path, callback)
+    // callback: function(/*int*/ nodeId)
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method resolveNode(/*int*/ nodeId, callback)
+    var result = Weinre.injectedScript.resolveNode(nodeId)
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method getNodeProperties(/*int*/ nodeId, /*any[]*/ propertiesArray, callback)
+    var propertiesArray = JSON.stringify(propertiesArray)
+    var result = Weinre.injectedScript.getNodeProperties(nodeId, propertiesArray)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method getNodePrototypes(/*int*/ nodeId, callback)
+    var result = Weinre.injectedScript.getNodePrototypes(nodeId)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method pushNodeToFrontend(/*any*/ objectId, callback)
+    var objectId = JSON.stringify(objectId)
+    var result = Weinre.injectedScript.pushNodeToFrontend(objectId)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
diff --git a/weinre.web/modules/weinre/target/WiDOMStorageImpl.scoop b/weinre.web/modules/weinre/target/WiDOMStorageImpl.scoop
new file mode 100644
index 0000000..cd42790
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiDOMStorageImpl.scoop
@@ -0,0 +1,27 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+
+//-----------------------------------------------------------------------------
+class WiDOMStorageImpl
+
+//-----------------------------------------------------------------------------
+method getDOMStorageEntries(/*int*/ storageId, callback)
+    // callback: function(/*any[]*/ entries)
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method setDOMStorageItem(/*int*/ storageId, /*string*/ key, /*string*/ value, callback)
+    // callback: function(/*boolean*/ success)
+    Weinre.notImplemented(arguments.callee.signature)
+
+//-----------------------------------------------------------------------------
+method removeDOMStorageItem(/*int*/ storageId, /*string*/ key, callback)
+    // callback: function(/*boolean*/ success)
+    Weinre.notImplemented(arguments.callee.signature)
\ No newline at end of file
diff --git a/weinre.web/modules/weinre/target/WiDatabaseImpl.scoop b/weinre.web/modules/weinre/target/WiDatabaseImpl.scoop
new file mode 100644
index 0000000..7b71765
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiDatabaseImpl.scoop
@@ -0,0 +1,23 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+
+//-----------------------------------------------------------------------------
+class WiDatabaseImpl
+
+//-----------------------------------------------------------------------------
+method getDatabaseTableNames(/*int*/ databaseId, callback)
+    // callback: function(/*any[]*/ tableNames)
+    Weinre.notImplemented(arguments.callee.signature)
+
+
+//-----------------------------------------------------------------------------
+method executeSQL(/*int*/ databaseId, /*string*/ query, callback)
+    // callback: function(/*boolean*/ success, /*int*/ transactionId)
+    Weinre.notImplemented(arguments.callee.signature)
diff --git a/weinre.web/modules/weinre/target/WiInspectorImpl.scoop b/weinre.web/modules/weinre/target/WiInspectorImpl.scoop
new file mode 100644
index 0000000..aed26ad
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiInspectorImpl.scoop
@@ -0,0 +1,65 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+requireClass ../target/Timeline
+
+//-----------------------------------------------------------------------------
+class WiInspectorImpl
+
+//-----------------------------------------------------------------------------
+method reloadPage(callback)
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+    window.location.reload()
+
+//-----------------------------------------------------------------------------
+method highlightDOMNode(/*int*/ nodeId, callback)
+    var node = Weinre.nodeStore.getNode(nodeId)
+    if (!node) {
+        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
+        return
+    }
+
+    Weinre.elementHighlighter.on(node)
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method hideDOMNodeHighlight(callback)
+    Weinre.elementHighlighter.off()
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+//-----------------------------------------------------------------------------
+method startTimelineProfiler(callback)
+    Timeline.start()
+    
+    Weinre.wi.TimelineNotify.timelineProfilerWasStarted()
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
+
+//-----------------------------------------------------------------------------
+method stopTimelineProfiler(callback)
+    Timeline.stop()
+    
+    Weinre.wi.TimelineNotify.timelineProfilerWasStopped()
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback)
+    }
+
diff --git a/weinre.web/modules/weinre/target/WiRuntimeImpl.scoop b/weinre.web/modules/weinre/target/WiRuntimeImpl.scoop
new file mode 100644
index 0000000..44cd0e9
--- /dev/null
+++ b/weinre.web/modules/weinre/target/WiRuntimeImpl.scoop
@@ -0,0 +1,55 @@
+
+/*
+ * weinre is available under *either* the terms of the modified BSD license *or* the
+ * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
+ * 
+ * Copyright (c) 2011 IBM Corporation
+ */
+
+requireClass ../common/Weinre
+
+//-----------------------------------------------------------------------------
+class WiRuntimeImpl
+
+//-----------------------------------------------------------------------------
+method evaluate(/*string*/ expression, /*string*/ objectGroup, /*boolean*/ includeCommandLineAPI, callback)
+    var result = Weinre.injectedScript.evaluate(expression, objectGroup, includeCommandLineAPI)
+    
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method getCompletions(/*string*/ expression, /*boolean*/ includeCommandLineAPI, callback)
+    var result = Weinre.injectedScript.getCompletions(expression, includeCommandLineAPI)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method getProperties(/*any*/ objectId, /*boolean*/ ignoreHasOwnProperty, /*boolean*/ abbreviate, callback)
+    var objectId = JSON.stringify(objectId)
+    var result = Weinre.injectedScript.getProperties(objectId, ignoreHasOwnProperty, abbreviate)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method setPropertyValue(/*any*/ objectId, /*string*/ propertyName, /*string*/ expression, callback)
+    var objectId = JSON.stringify(objectId)
+    var result = Weinre.injectedScript.setPropertyValue(objectId, propertyName, expression)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+
+//-----------------------------------------------------------------------------
+method releaseWrapperObjectGroup(/*int*/ injectedScriptId, /*string*/ objectGroup, callback)
+    var result = Weinre.injectedScript.releaseWrapperObjectGroup(objectGroupName)
+
+    if (callback) {
+        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
+    }
+    
\ No newline at end of file