Branch merge for bug 462441.
authorReed Loden <reed@reedloden.com>
Fri, 16 Jan 2009 01:01:10 -0600
changeset 23789 2739ea3ae5acdf83555f38b77fbb1f7a3a654b86
parent 23788 9ec0ab99182ebdb381c372df810915df41b9dfcc (current diff)
parent 23787 09ac7c3e27e7efd6ed3fb75133dba051fcc3fb7d (diff)
child 23790 95f52854608a043b4e62df04418f3db1f0f7f0b5
push id4724
push userreed@reedloden.com
push dateFri, 16 Jan 2009 07:01:23 +0000
treeherdermozilla-central@2739ea3ae5ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs462441
milestone1.9.2a1pre
Branch merge for bug 462441.
build/pgo/quit.js
dom/tests/mochitest/ajax/prototype/test/unit/ajax.html
dom/tests/mochitest/ajax/prototype/test/unit/array.html
dom/tests/mochitest/ajax/prototype/test/unit/base.html
dom/tests/mochitest/ajax/prototype/test/unit/dom.html
dom/tests/mochitest/ajax/prototype/test/unit/element_mixins.html
dom/tests/mochitest/ajax/prototype/test/unit/enumerable.html
dom/tests/mochitest/ajax/prototype/test/unit/form.html
dom/tests/mochitest/ajax/prototype/test/unit/hash.html
dom/tests/mochitest/ajax/prototype/test/unit/position.html
dom/tests/mochitest/ajax/prototype/test/unit/range.html
dom/tests/mochitest/ajax/prototype/test/unit/selector.html
dom/tests/mochitest/ajax/prototype/test/unit/string.html
dom/tests/mochitest/ajax/prototype/test/unit/unit_tests.html
js/src/js.cpp
layout/xul/base/src/nsIScrollbarListener.h
toolkit/components/passwordmgr/test/unit/key3.db
toolkit/locales/en-US/installer/windows/charset.mk
toolkit/mozapps/installer/windows/nsis/Processes.dll
toolkit/xre/nsIXULRuntime.idl
widget/src/windows/nsWindow.h
--- a/accessible/public/nsIAccessibilityService.idl
+++ b/accessible/public/nsIAccessibilityService.idl
@@ -47,39 +47,39 @@ interface nsIContent;
 interface nsITimer;
 
 [uuid(44685af8-18be-494a-8e64-16c7d4296dd1)]
 interface nsIAccessibilityService : nsIAccessibleRetrieval
 {
   nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
   nsIAccessible createRootAccessible(in nsIPresShell aShell, in nsIDocument aDocument);
 
-  nsIAccessible createHTML4ButtonAccessible(in nsISupports aFrame);
-  nsIAccessible createHyperTextAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLBRAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLButtonAccessible(in nsISupports aFrame);
+  nsIAccessible createHTML4ButtonAccessible(in nsIFrame aFrame);
+  nsIAccessible createHyperTextAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLBRAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLButtonAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLAccessibleByMarkup(in nsIFrame aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode);
-  nsIAccessible createHTMLLIAccessible(in nsISupports aFrame, in nsISupports aBulletFrame, in AString aBulletText);
-  nsIAccessible createHTMLCheckboxAccessible(in nsISupports aFrame);
+  nsIAccessible createHTMLLIAccessible(in nsIFrame aFrame, in nsIFrame aBulletFrame, in AString aBulletText);
+  nsIAccessible createHTMLCheckboxAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLComboboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);
-  nsIAccessible createHTMLGenericAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLGroupboxAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLHRAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLImageAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLLabelAccessible(in nsISupports aFrame);
+  nsIAccessible createHTMLGenericAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLGroupboxAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLHRAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLImageAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLLabelAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLListboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);
   nsIAccessible createHTMLObjectFrameAccessible(in nsObjectFrame aFrame);
-  nsIAccessible createHTMLRadioButtonAccessible(in nsISupports aFrame);
+  nsIAccessible createHTMLRadioButtonAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLSelectOptionAccessible(in nsIDOMNode aNode, in nsIAccessible aAccParent, in nsIWeakReference aPresShell);
-  nsIAccessible createHTMLTableAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLTableCellAccessible(in nsISupports aFrame);
+  nsIAccessible createHTMLTableAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLTableCellAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLTableHeadAccessible(in nsIDOMNode aDOMNode);
-  nsIAccessible createHTMLTextAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLTextFieldAccessible(in nsISupports aFrame);
-  nsIAccessible createHTMLCaptionAccessible(in nsISupports aFrame);
+  nsIAccessible createHTMLTextAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLTextFieldAccessible(in nsIFrame aFrame);
+  nsIAccessible createHTMLCaptionAccessible(in nsIFrame aFrame);
 
   nsIAccessible getAccessible(in nsIDOMNode aNode, in nsIPresShell aPresShell,                          
                               in nsIWeakReference aWeakShell, 
                               inout nsIFrame frameHint, out boolean aIsHidden);
 
   // For gtk+ native window accessible
   nsIAccessible addNativeRootAccessible(in voidPtr aAtkAccessible);
   void removeNativeRootAccessible(in nsIAccessible aRootAccessible);
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -263,36 +263,36 @@ nsAccUtils::SetAccAttrsForXULContainerIt
   SetAccGroupAttrs(aAttributes, level, posInSet, setSize);
 }
 
 void
 nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
                                        nsIContent *aStartContent,
                                        nsIContent *aTopContent)
 {
-  nsAutoString atomic, live, relevant, channel, busy;
+  nsAutoString atomic, live, relevant, busy;
   nsIContent *ancestor = aStartContent;
   while (ancestor) {
     if (relevant.IsEmpty() &&
+        nsAccUtils::HasDefinedARIAToken(ancestor, nsAccessibilityAtoms::aria_relevant) &&
         ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
       SetAccAttr(aAttributes, nsAccessibilityAtoms::containerRelevant, relevant);
 
     if (live.IsEmpty() &&
+        nsAccUtils::HasDefinedARIAToken(ancestor, nsAccessibilityAtoms::aria_live) &&
         ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live, live))
       SetAccAttr(aAttributes, nsAccessibilityAtoms::containerLive, live);
 
-    if (channel.IsEmpty() &&
-        ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel, channel))
-      SetAccAttr(aAttributes, nsAccessibilityAtoms::containerChannel, channel);
-
     if (atomic.IsEmpty() &&
+        nsAccUtils::HasDefinedARIAToken(ancestor, nsAccessibilityAtoms::aria_atomic) &&
         ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
       SetAccAttr(aAttributes, nsAccessibilityAtoms::containerAtomic, atomic);
 
     if (busy.IsEmpty() &&
+        nsAccUtils::HasDefinedARIAToken(ancestor, nsAccessibilityAtoms::aria_busy) &&
         ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy, busy))
       SetAccAttr(aAttributes, nsAccessibilityAtoms::containerBusy, busy);
 
     if (ancestor == aTopContent)
       break;
 
     ancestor = ancestor->GetParent();
     if (!ancestor)
@@ -322,16 +322,29 @@ nsAccUtils::IsARIAPropForObjectAttr(nsIA
     aAtom != nsAccessibilityAtoms::aria_required &&
     aAtom != nsAccessibilityAtoms::aria_selected &&
     aAtom != nsAccessibilityAtoms::aria_valuemax &&
     aAtom != nsAccessibilityAtoms::aria_valuemin &&
     aAtom != nsAccessibilityAtoms::aria_valuenow &&
     aAtom != nsAccessibilityAtoms::aria_valuetext;
 }
 
+PRBool
+nsAccUtils::HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom)
+{
+  if (!aContent->HasAttr(kNameSpaceID_None, aAtom) ||
+      aContent->AttrValueIs(kNameSpaceID_None, aAtom,
+                            nsAccessibilityAtoms::_empty, eCaseMatters) ||
+      aContent->AttrValueIs(kNameSpaceID_None, aAtom,
+                            nsAccessibilityAtoms::_undefined, eCaseMatters)) {
+        return PR_FALSE;
+  }
+  return PR_TRUE;
+}
+
 nsresult
 nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
                          PRBool aIsAsynch)
 {
   NS_ENSURE_ARG(aAccessible);
 
   nsCOMPtr<nsPIAccessible> pAccessible(do_QueryInterface(aAccessible));
   NS_ASSERTION(pAccessible, "Accessible doesn't implement nsPIAccessible");
@@ -368,17 +381,18 @@ nsAccUtils::GetAncestorWithRole(nsIAcces
 void
 nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
                                   nsIContent *aStartContent,
                                   nsIAccessible **aTreeItemParentResult)
 {
   *aTreeItemParentResult = nsnull;
   nsAutoString levelStr;
   PRInt32 level = 0;
-  if (aStartContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, levelStr)) {
+  if (nsAccUtils::HasDefinedARIAToken(aStartContent, nsAccessibilityAtoms::aria_level) &&
+      aStartContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, levelStr)) {
     // This is a tree that uses aria-level to define levels, so find the first previous
     // sibling accessible where level is defined to be less than the current level
     PRInt32 success;
     level = levelStr.ToInteger(&success);
     if (level > 1 && NS_SUCCEEDED(success)) {
       nsCOMPtr<nsIAccessible> currentAccessible = aStartTreeItem, prevAccessible;
       while (PR_TRUE) {
         currentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
@@ -390,16 +404,18 @@ nsAccUtils::GetARIATreeItemParent(nsIAcc
         PRUint32 role;
         currentAccessible->GetFinalRole(&role);
         if (role != nsIAccessibleRole::ROLE_OUTLINEITEM)
           continue;
         nsCOMPtr<nsIDOMNode> treeItemNode;
         accessNode->GetDOMNode(getter_AddRefs(treeItemNode));
         nsCOMPtr<nsIContent> treeItemContent = do_QueryInterface(treeItemNode);
         if (treeItemContent &&
+            nsAccUtils::HasDefinedARIAToken(treeItemContent,
+                                     nsAccessibilityAtoms::aria_level) &&
             treeItemContent->GetAttr(kNameSpaceID_None,
                                      nsAccessibilityAtoms::aria_level, levelStr)) {
           if (levelStr.ToInteger(&success) < level && NS_SUCCEEDED(success)) {
             NS_ADDREF(*aTreeItemParentResult = currentAccessible);
             return;
           }
         }
       }
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -132,16 +132,25 @@ public:
 
   /**
    * Return PR_TRUE if the ARIA property should always be exposed as an object
    * attribute.
    */
   static PRBool IsARIAPropForObjectAttr(nsIAtom *aAtom);
 
   /**
+   * Any ARIA property of type boolean or NMTOKEN is undefined if the ARIA
+   * property is not present, or is "" or "undefined". Do not call 
+   * this method for properties of type string, decimal, IDREF or IDREFS.
+   * 
+   * Return PR_TRUE if the ARIA property is defined, otherwise PR_FALSE
+   */
+  static PRBool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
+
+  /**
    * Fire accessible event of the given type for the given accessible.
    */
   static nsresult FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
                                PRBool aIsAsynch = PR_FALSE);
 
   /**
     * If an ancestor in this document exists with the given role, return it
     * @param aDescendant Descendant to start search with
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -59,16 +59,17 @@
 ACCESSIBILITY_ATOM(_empty, "")
 ACCESSIBILITY_ATOM(button, "button")
 ACCESSIBILITY_ATOM(_false, "false")
 ACCESSIBILITY_ATOM(image, "image")
 ACCESSIBILITY_ATOM(password, "password")
 ACCESSIBILITY_ATOM(reset, "reset")
 ACCESSIBILITY_ATOM(submit, "submit")
 ACCESSIBILITY_ATOM(_true, "true")
+ACCESSIBILITY_ATOM(_undefined, "undefined")
 
   // Header info
 ACCESSIBILITY_ATOM(headerContentLanguage, "content-language")
 
   // Alphabetical list of frame types
 ACCESSIBILITY_ATOM(areaFrame, "AreaFrame")
 ACCESSIBILITY_ATOM(blockFrame, "BlockFrame")
 ACCESSIBILITY_ATOM(boxFrame, "BoxFrame")
@@ -199,20 +200,18 @@ ACCESSIBILITY_ATOM(language, "language")
   // ARIA (DHTML accessibility) attributes
   // Also add to nsARIAMap.cpp and nsARIAMap.h
   // ARIA role attribute
 ACCESSIBILITY_ATOM(role, "role")
 ACCESSIBILITY_ATOM(aria_activedescendant, "aria-activedescendant")
 ACCESSIBILITY_ATOM(aria_atomic, "aria-atomic")
 ACCESSIBILITY_ATOM(aria_autocomplete, "aria-autocomplete")
 ACCESSIBILITY_ATOM(aria_busy, "aria-busy")
-ACCESSIBILITY_ATOM(aria_channel, "aria-channel")
 ACCESSIBILITY_ATOM(aria_checked, "aria-checked")
 ACCESSIBILITY_ATOM(aria_controls, "aria-controls")
-ACCESSIBILITY_ATOM(aria_datatype, "aria-datatype")
 ACCESSIBILITY_ATOM(aria_describedby, "aria-describedby")
 ACCESSIBILITY_ATOM(aria_droppable, "aria-droppable")
 ACCESSIBILITY_ATOM(aria_disabled, "aria-disabled")
 ACCESSIBILITY_ATOM(aria_dropeffect, "aria-dropeffect")
 ACCESSIBILITY_ATOM(aria_expanded, "aria-expanded")
 ACCESSIBILITY_ATOM(aria_flowto, "aria-flowto")
 ACCESSIBILITY_ATOM(aria_grab, "aria-grab")
 ACCESSIBILITY_ATOM(aria_haspopup, "aria-haspopup")
@@ -241,15 +240,14 @@ ACCESSIBILITY_ATOM(aria_valuetext, "aria
 // a form property used to obtain the default label
 // of an HTML button from the button frame
 ACCESSIBILITY_ATOM(defaultLabel, "defaultLabel")
 
 // Object attributes
 ACCESSIBILITY_ATOM(tableCellIndex, "table-cell-index")
 ACCESSIBILITY_ATOM(containerAtomic, "container-atomic")
 ACCESSIBILITY_ATOM(containerBusy, "container-busy")
-ACCESSIBILITY_ATOM(containerChannel, "container-channel")
 ACCESSIBILITY_ATOM(containerLive, "container-live")
 ACCESSIBILITY_ATOM(containerRelevant, "container-relevant")
 ACCESSIBILITY_ATOM(level, "level")
 ACCESSIBILITY_ATOM(lineNumber, "line-number")
 ACCESSIBILITY_ATOM(posinset, "posinset") 
 ACCESSIBILITY_ATOM(setsize, "setsize")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -327,21 +327,20 @@ NS_IMETHODIMP nsAccessibilityService::On
   nsIRequest *aRequest, PRUint32 state)
 {
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
   return NS_OK;
 }
 
 
 nsresult
-nsAccessibilityService::GetInfo(nsISupports* aFrame, nsIFrame** aRealFrame, nsIWeakReference** aShell, nsIDOMNode** aNode)
+nsAccessibilityService::GetInfo(nsIFrame* aFrame, nsIWeakReference** aShell, nsIDOMNode** aNode)
 {
   NS_ASSERTION(aFrame,"Error -- 1st argument (aFrame) is null!!");
-  *aRealFrame = static_cast<nsIFrame*>(aFrame);
-  nsCOMPtr<nsIContent> content = (*aRealFrame)->GetContent();
+  nsCOMPtr<nsIContent> content = aFrame->GetContent();
   nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
   if (!content || !node)
     return NS_ERROR_FAILURE;
   *aNode = node;
   NS_IF_ADDREF(*aNode);
 
   nsCOMPtr<nsIDocument> document = content->GetDocument();
   if (!document)
@@ -469,40 +468,38 @@ nsAccessibilityService::CreateRootAccess
 
   return NS_OK;
 }
 
  /**
    * HTML widget creation
    */
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTML4ButtonAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTML4ButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTML4ButtonAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLButtonAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLButtonAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
@@ -560,63 +557,60 @@ nsAccessibilityService::CreateHTMLAccess
            tag == nsAccessibilityAtoms::q) {
     return CreateHyperTextAccessible(aFrame, aAccessible);
   }
   NS_IF_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLLIAccessible(nsISupports *aFrame, 
-                                               nsISupports *aBulletFrame,
+nsAccessibilityService::CreateHTMLLIAccessible(nsIFrame *aFrame, 
+                                               nsIFrame *aBulletFrame,
                                                const nsAString& aBulletText,
                                                nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLLIAccessible(node, weakShell, aBulletText);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHyperTextAccessible(nsISupports *aFrame, nsIAccessible **aAccessible)
+nsAccessibilityService::CreateHyperTextAccessible(nsIFrame *aFrame, nsIAccessible **aAccessible)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
   
   *aAccessible = new nsHyperTextAccessibleWrap(node, weakShell);
   NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
 
   NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLCheckboxAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLCheckboxAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
@@ -630,22 +624,21 @@ nsAccessibilityService::CreateHTMLCombob
   if (! *_retval)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLImageAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLImageAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = nsnull;
   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(node));
   if (domElement) {
       *_retval = new nsHTMLImageAccessibleWrap(node, weakShell);
   }
@@ -653,28 +646,27 @@ nsAccessibilityService::CreateHTMLImageA
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLGenericAccessible(nsISupports *aFrame, nsIAccessible **aAccessible)
+nsAccessibilityService::CreateHTMLGenericAccessible(nsIFrame *aFrame, nsIAccessible **aAccessible)
 {
   return CreateHyperTextAccessible(aFrame, aAccessible);
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLGroupboxAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLGroupboxAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
@@ -702,21 +694,20 @@ nsAccessibilityService::CreateHTMLListbo
   *     the object element DOMNode
   */
 NS_IMETHODIMP
 nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame *aFrame,
                                                         nsIAccessible **aAccessible)
 {
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsIFrame *frame;
-  GetInfo(static_cast<nsIFrame*>(aFrame), &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
 
   *aAccessible = nsnull;
-  if (!frame || frame->GetRect().IsEmpty()) {
+  if (aFrame->GetRect().IsEmpty()) {
     return NS_ERROR_FAILURE;
   }
   // 1) for object elements containing either HTML or TXT documents
   nsCOMPtr<nsIDOMDocument> domDoc;
   nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(node));
   if (obj)
     obj->GetContentDocument(getter_AddRefs(domDoc));
   else
@@ -738,30 +729,29 @@ nsAccessibilityService::CreateHTMLObject
         return NS_OK;
       }
     }
   }
 #endif
 
   // 3) for images and imagemaps, or anything else with a child frame
   // we have the object frame, get the image frame
-  frame = aFrame->GetFirstChild(nsnull);
+  nsIFrame *frame = aFrame->GetFirstChild(nsnull);
   if (frame)
     return frame->GetAccessible(aAccessible);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLRadioButtonAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
@@ -778,22 +768,21 @@ nsAccessibilityService::CreateHTMLSelect
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLTableAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTableAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLTableAccessibleWrap(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
@@ -823,133 +812,126 @@ nsAccessibilityService::CreateHTMLTableH
   *_retval = static_cast<nsIAccessible *>(accTableHead);
   NS_IF_ADDREF(*_retval);
 
   return rv;
 #endif
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLTableCellAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTableCellAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLTableCellAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLTextAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTextAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
   *_retval = nsnull;
 
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   // XXX Don't create ATK objects for these
   *_retval = new nsHTMLTextAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLTextFieldAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLTextFieldAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLLabelAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLLabelAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLLabelAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLHRAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLHRAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLHRAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLBRAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLBRAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLBRAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLCaptionAccessible(nsISupports *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLCaptionAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
-  nsIFrame* frame;
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
   *_retval = new nsHTMLCaptionAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
@@ -1405,18 +1387,17 @@ NS_IMETHODIMP nsAccessibilityService::Ge
 #endif
       if (frame->GetContent() != content) {
         // Not the main content for this frame!
         // For example, this happens because <area> elements return the
         // image frame as their primary frame. The main content for the 
         // image frame is the image content.
 
         // Check if frame is an image frame, and content is <area>
-        nsIImageFrame *imageFrame;
-        CallQueryInterface(frame, &imageFrame);
+        nsIImageFrame *imageFrame = do_QueryFrame(frame);
         nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(content);
         if (imageFrame && areaElmt) {
           nsCOMPtr<nsIAccessible> imageAcc;
           CreateHTMLImageAccessible(frame, getter_AddRefs(imageAcc));
           if (imageAcc) {
             // cache children
             PRInt32 childCount;
             imageAcc->GetChildCount(&childCount);
@@ -1613,34 +1594,33 @@ NS_IMETHODIMP nsAccessibilityService::Ge
 
   return InitAccessible(newAcc, aAccessible, roleMapEntry);
 }
 
 PRBool
 nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent,
                                                  nsIWeakReference *aWeakShell)
 {
-  return aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel) ||
+  // ARIA attributes that take token values (NMTOKEN, bool) are special cased.
+  return nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_atomic) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_busy) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_controls) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_datatype) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_describedby) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_dropeffect) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_dropeffect) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_flowto) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_grab) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_haspopup) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_invalid) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_grab) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_haspopup) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_invalid) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_labelledby) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_owns) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_required) ||
-         aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_sort);
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_live) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_owns) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_required) ||
+         nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_sort);
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
                                                   nsIDOMNode **aRelevantNode)
 {
   // The method returns node that is relevant for attached accessible check.
   // Sometimes element that is XBL widget hasn't accessible children in
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -84,22 +84,21 @@ public:
    */
   static nsresult GetAccessibilityService(nsIAccessibilityService** aResult);
 
 private:
   /**
    * Return presentation shell, DOM node for the given frame.
    *
    * @param aFrame - the given frame
-   * @param aRealFrame [out] - the given frame casted to nsIFrame
    * @param aShell [out] - presentation shell for DOM node associated with the
    *                 given frame
    * @param aContent [out] - DOM node associated with the given frame
    */
-  nsresult GetInfo(nsISupports *aFrame, nsIFrame **aRealFrame,
+  nsresult GetInfo(nsIFrame *aFrame,
                    nsIWeakReference **aShell,
                    nsIDOMNode **aContent);
 
   /**
    * Initialize an accessible and cache it. The method should be called for
    * every created accessible.
    *
    * @param aAccessibleIn - accessible to initialize.
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1332,17 +1332,17 @@ NS_IMETHODIMP nsAccessible::GetBounds(PR
 
   *x      = presContext->AppUnitsToDevPixels(unionRectTwips.x); 
   *y      = presContext->AppUnitsToDevPixels(unionRectTwips.y);
   *width  = presContext->AppUnitsToDevPixels(unionRectTwips.width);
   *height = presContext->AppUnitsToDevPixels(unionRectTwips.height);
 
   // We have the union of the rectangle, now we need to put it in absolute screen coords
 
-  nsRect orgRectPixels = aBoundingFrame->GetScreenRectExternal();
+  nsIntRect orgRectPixels = aBoundingFrame->GetScreenRectExternal();
   *x += orgRectPixels.x;
   *y += orgRectPixels.y;
 
   return NS_OK;
 }
 
 // helpers
 
@@ -1897,19 +1897,19 @@ NS_IMETHODIMP nsAccessible::GetFinalRole
   if (mRoleMapEntry) {
     *aRole = mRoleMapEntry->role;
 
     // These unfortunate exceptions don't fit into the ARIA table
     // This is where the nsIAccessible role depends on both the role and ARIA state
     if (*aRole == nsIAccessibleRole::ROLE_PUSHBUTTON) {
       nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
       if (content) {
-        if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_pressed)) {
-          // For aria-pressed="false" or aria-pressed="true"
-          // For simplicity, any pressed attribute indicates it's a toggle button
+        if (nsAccUtils::HasDefinedARIAToken(content, nsAccessibilityAtoms::aria_pressed)) {
+          // For simplicity, any existing pressed attribute except "", or "undefined"
+          // indicates a toggle
           *aRole = nsIAccessibleRole::ROLE_TOGGLE_BUTTON;
         }
         else if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_haspopup,
                                       nsAccessibilityAtoms::_true, eCaseMatters)) {
           // For button with aria-haspopup="true"
           *aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
         }
       }
@@ -2176,16 +2176,27 @@ nsAccessible::GroupPosition(PRInt32 *aGr
 PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut,
                                      nsStateMapEntry *aStateMapEntry)
 {
   // Return true if we should continue
   if (!aStateMapEntry->attributeName) {
     return PR_FALSE;  // Stop looking -- no more states
   }
 
+  // We only have attribute state mappings for NMTOKEN (and boolean) based
+  // ARIA attributes. According to spec, a value of "undefined" is to be
+  // treated equivalent to "", or the absence of the attribute. We bail out
+  // for this case here.
+  // Note: If this method happens to be called with a non-token based
+  // attribute, for example: aria-label="" or aria-label="undefined", we will
+  // bail out and not explore a state mapping, which is safe.
+  if (!nsAccUtils::HasDefinedARIAToken(aContent, *aStateMapEntry->attributeName)) {
+    return PR_TRUE;
+  }
+  
   nsAutoString attribValue;
   if (aContent->GetAttr(kNameSpaceID_None, *aStateMapEntry->attributeName, attribValue)) {
     if (aStateMapEntry->attributeValue == kBoolState) {
       // No attribute value map specified in state map entry indicates state cleared
       if (attribValue.EqualsLiteral("false")) {
         *aStateInOut &= ~aStateMapEntry->state;
       }
       else {
@@ -2769,18 +2780,17 @@ NS_IMETHODIMP nsAccessible::GetAccessibl
       // If accessible is in its own Window then we should provide NODE_CHILD_OF relation
       // so that MSAA clients can easily get to true parent instead of getting to oleacc's
       // ROLE_WINDOW accessible which will prevent us from going up further (because it is
       // system generated and has no idea about the hierarchy above it).
       nsIFrame *frame = GetFrame();
       if (frame) {
         nsIView *view = frame->GetViewExternal();
         if (view) {
-          nsIScrollableFrame *scrollFrame = nsnull;
-          CallQueryInterface(frame, &scrollFrame);
+          nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
           if (scrollFrame || view->GetWidget()) {
             return GetParent(aRelated);
           }
         }
       }
       break;
     }
   case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -285,20 +285,20 @@ nsCaretAccessible::SpellcheckSelectionCh
   nsCOMPtr<nsIAccessibleEvent> event =
     new nsAccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
                    acc, nsnull);
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   return mRootAccessible->FireAccessibleEvent(event);
 }
 
-nsRect
+nsIntRect
 nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
 {
-  nsRect caretRect;
+  nsIntRect caretRect;
   NS_ENSURE_TRUE(aOutWidget, caretRect);
   *aOutWidget = nsnull;
   NS_ENSURE_TRUE(mRootAccessible, caretRect);
 
   if (!mLastTextAccessible) {
     return caretRect;    // Return empty rect
   }
 
@@ -317,38 +317,37 @@ nsCaretAccessible::GetCaretRect(nsIWidge
   presShell->GetCaret(getter_AddRefs(caret));
   NS_ENSURE_TRUE(caret, caretRect);
 
   PRBool isCollapsed;
   nsIView *view;
   nsCOMPtr<nsISelection> caretSelection(do_QueryReferent(mLastUsedSelection));
   NS_ENSURE_TRUE(caretSelection, caretRect);
   
+  nsRect rect;
   caret->GetCaretCoordinates(nsCaret::eRenderingViewCoordinates, caretSelection,
-                             &caretRect, &isCollapsed, &view);
-  if (!view || caretRect.IsEmpty()) {
-    return nsRect(); // Return empty rect
+                             &rect, &isCollapsed, &view);
+  if (!view || rect.IsEmpty()) {
+    return nsIntRect(); // Return empty rect
   }
 
   PRBool isVisible;
   caret->GetCaretVisible(&isVisible);
   if (!isVisible) {
-    return nsRect();  // Return empty rect
+    return nsIntRect();  // Return empty rect
   }
   nsPoint offsetFromWidget;
   *aOutWidget = view->GetNearestWidget(&offsetFromWidget);
-  NS_ENSURE_TRUE(*aOutWidget, nsRect());
+  NS_ENSURE_TRUE(*aOutWidget, nsIntRect());
 
   nsPresContext *presContext = presShell->GetPresContext();
-  NS_ENSURE_TRUE(presContext, nsRect());
+  NS_ENSURE_TRUE(presContext, nsIntRect());
 
-  caretRect.x = presContext->AppUnitsToDevPixels(caretRect.x + offsetFromWidget.x);
-  caretRect.y = presContext->AppUnitsToDevPixels(caretRect.y + offsetFromWidget.y);
-  caretRect.width = presContext->AppUnitsToDevPixels(caretRect.width);
-  caretRect.height = presContext->AppUnitsToDevPixels(caretRect.height);
+  rect += offsetFromWidget;
+  caretRect = nsRect::ToOutsidePixels(rect, presContext->AppUnitsPerDevPixel());
 
   (*aOutWidget)->WidgetToScreen(caretRect, caretRect);
 
   // Correct for character size, so that caret always matches the size of the character
   // This is important for font size transitions, and is necessary because the Gecko caret uses the
   // previous character's size as the user moves forward in the text by character.
   PRInt32 charX, charY, charWidth, charHeight;
   if (NS_SUCCEEDED(mLastTextAccessible->GetCharacterExtents(mLastCaretOffset, &charX, &charY,
--- a/accessible/src/base/nsCaretAccessible.h
+++ b/accessible/src/base/nsCaretAccessible.h
@@ -114,17 +114,17 @@ public:
    * If the document goes away, this method needs to be called for 
    * that document by the owner of the caret. We use presShell because
    * instead of document because it is more direct than getting it from
    * the document, and in any case it is unavailable from the doc after a pagehide.
    * @param aShell   PresShell for document to no longer listen to selection events from.
    */
   nsresult RemoveDocSelectionListener(nsIPresShell *aShell);
 
-  nsRect GetCaretRect(nsIWidget **aOutWidget);
+  nsIntRect GetCaretRect(nsIWidget **aOutWidget);
 
 protected:
   nsresult NormalSelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel);
   nsresult SpellcheckSelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel);
 
   already_AddRefed<nsISelectionController>
   GetSelectionControllerForNode(nsIDOMNode *aNode);
 
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -326,18 +326,17 @@ nsCoreUtils::ScrollSubstringTo(nsIFrame 
   return NS_OK;
 }
 
 void
 nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
                                 nsIFrame *aFrame,
                                 const nsIntPoint& aPoint)
 {
-  nsIScrollableFrame *scrollableFrame = nsnull;
-  CallQueryInterface(aScrollableFrame, &scrollableFrame);
+  nsIScrollableFrame *scrollableFrame = do_QueryFrame(aScrollableFrame);
   if (!scrollableFrame)
     return;
 
   nsPresContext *presContext = aFrame->PresContext();
 
   nsIntRect frameRect = aFrame->GetScreenRectExternal();
   PRInt32 devDeltaX = aPoint.x - frameRect.x;
   PRInt32 devDeltaY = aPoint.y - frameRect.y;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1055,17 +1055,23 @@ nsDocAccessible::AttributeChangedImpl(ns
   // DOM attribute & resulting layout to actually change. Otherwise,
   // assistive technology will retrieve the wrong state/value/selection info.
 
   // XXX todo
   // We still need to handle special HTML cases here
   // For example, if an <img>'s usemap attribute is modified
   // Otherwise it may just be a state change, for example an object changing
   // its visibility
-
+  // 
+  // XXX todo: report aria state changes for "undefined" literal value changes
+  // filed as bug 472142
+  //
+  // XXX todo:  invalidate accessible when aria state changes affect exposed role
+  // filed as bug 472143
+  
   nsCOMPtr<nsISupports> container = mDocument->GetContainer();
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
   if (!docShell) {
     return;
   }
 
   PRUint32 busyFlags;
   docShell->GetBusyFlags(&busyFlags);
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -836,18 +836,17 @@ nsresult nsRootAccessible::HandleEventWi
       }
 #endif
       nsRefPtr<nsAccessNode> menuAccessNode =
         nsAccUtils::QueryAccessNode(accessible);
   
       nsIFrame* menuFrame = menuAccessNode->GetFrame();
       NS_ENSURE_TRUE(menuFrame, NS_ERROR_FAILURE);
 
-      nsIMenuFrame* imenuFrame;
-      CallQueryInterface(menuFrame, &imenuFrame);
+      nsIMenuFrame* imenuFrame = do_QueryFrame(menuFrame);
       if (imenuFrame)
         fireFocus = PR_TRUE;
       // QI failed for nsIMenuFrame means it's not on menu bar
       if (imenuFrame && imenuFrame->IsOnMenuBar() &&
                        !imenuFrame->IsOnActiveMenuBar()) {
         // It is a top level menuitem. Only fire a focus event when the menu bar
         // is active.
         return NS_OK;
--- a/accessible/src/html/nsHTMLAreaAccessible.cpp
+++ b/accessible/src/html/nsHTMLAreaAccessible.cpp
@@ -115,37 +115,38 @@ nsHTMLAreaAccessible::GetChildCount(PRIn
   *aCount = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y,
                                 PRInt32 *width, PRInt32 *height)
 {
+  nsresult rv;
+
   // Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame
 
   *x = *y = *width = *height = 0;
 
   nsPresContext *presContext = GetPresContext();
   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIContent> ourContent(do_QueryInterface(mDOMNode));
   NS_ENSURE_TRUE(ourContent, NS_ERROR_FAILURE);
 
   nsIFrame *frame = GetFrame();
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
-  nsIImageFrame *imageFrame;
-  nsresult rv = frame->QueryInterface(NS_GET_IID(nsIImageFrame), (void**)&imageFrame);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsIImageFrame *imageFrame = do_QueryFrame(frame);
 
   nsCOMPtr<nsIImageMap> map;
   imageFrame->GetImageMap(presContext, getter_AddRefs(map));
   NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
-  nsRect rect, orgRectPixels;
+  nsRect rect;
+  nsIntRect orgRectPixels;
   rv = map->GetBoundsForAreaContent(ourContent, presContext, rect);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *x      = presContext->AppUnitsToDevPixels(rect.x); 
   *y      = presContext->AppUnitsToDevPixels(rect.y); 
 
   // XXX Areas are screwy; they return their rects as a pair of points, one pair
   // stored into the width and height.
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -287,18 +287,17 @@ nsHTMLButtonAccessible::GetNameInternal(
   nsAutoString name;
   if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::value,
                         name) &&
       !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt,
                         name)) {
     // Use the button's (default) label if nothing else works
     nsIFrame* frame = GetFrame();
     if (frame) {
-      nsIFormControlFrame* fcFrame = nsnull;
-      CallQueryInterface(frame, &fcFrame);
+      nsIFormControlFrame* fcFrame = do_QueryFrame(frame);
       if (fcFrame)
         fcFrame->GetFormProperty(nsAccessibilityAtoms::defaultLabel, name);
     }
   }
 
   if (name.IsEmpty() &&
       !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::src,
                         name)) {
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -738,24 +738,22 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessib
     nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
     nsCOMPtr<nsIContent> selectContent(do_QueryInterface(testSelectNode));
     nsCOMPtr<nsIDOMHTMLOptionElement> option(do_QueryInterface(mDOMNode));
 
     if (!testSelectNode || !selectContent || !presShell || !option) 
       return NS_ERROR_FAILURE;
 
     nsIFrame *selectFrame = presShell->GetPrimaryFrameFor(selectContent);
-    nsIComboboxControlFrame *comboBoxFrame = nsnull;
-    CallQueryInterface(selectFrame, &comboBoxFrame);
+    nsIComboboxControlFrame *comboBoxFrame = do_QueryFrame(selectFrame);
     if (comboBoxFrame) {
       nsIFrame *listFrame = comboBoxFrame->GetDropDown();
       if (comboBoxFrame->IsDroppedDown() && listFrame) {
         // use this list control frame to roll up the list
-        nsIListControlFrame *listControlFrame = nsnull;
-        listFrame->QueryInterface(NS_GET_IID(nsIListControlFrame), (void**)&listControlFrame);
+        nsIListControlFrame *listControlFrame = do_QueryFrame(listFrame);
         if (listControlFrame) {
           PRInt32 newIndex = 0;
           option->GetIndex(&newIndex);
           listControlFrame->ComboboxFinish(newIndex);
         }
       }
     }
     return NS_OK;
@@ -792,18 +790,17 @@ nsresult nsHTMLSelectOptionAccessible::G
   // Get options
   nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(aListNode));
   NS_ASSERTION(selectElement, "No select element where it should be");
 
   nsCOMPtr<nsIDOMHTMLOptionsCollection> options;
   nsresult rv = selectElement->GetOptions(getter_AddRefs(options));
   
   if (NS_SUCCEEDED(rv)) {
-    nsIListControlFrame *listFrame = nsnull;
-    frame->QueryInterface(NS_GET_IID(nsIListControlFrame), (void**)&listFrame);
+    nsIListControlFrame *listFrame = do_QueryFrame(frame);
     if (listFrame) {
       // Get what's focused in listbox by asking frame for "selected item". 
       // Can't use dom interface for this, because it will always return the first selected item
       // when there is more than 1 item selected. We need the focused item, not
       // the first selected item.
       focusedOptionIndex = listFrame->GetSelectedIndex();
       if (focusedOptionIndex == -1) {
         nsCOMPtr<nsIDOMNode> nextOption;
@@ -1011,18 +1008,17 @@ void nsHTMLComboboxAccessible::CacheChil
     buttonAccessible->Init();
     mAccChildCount = 2; // Button accessible child successfully added
 #endif
 
     nsIFrame *frame = GetFrame();
     if (!frame) {
       return;
     }
-    nsIComboboxControlFrame *comboFrame = nsnull;
-    frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
+    nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
     if (!comboFrame) {
       return;
     }
     nsIFrame *listFrame = comboFrame->GetDropDown();
     if (!listFrame) {
       return;
     }
 
@@ -1071,21 +1067,17 @@ nsresult
 nsHTMLComboboxAccessible::GetStateInternal(PRUint32 *aState,
                                            PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   nsIFrame *frame = GetBoundsFrame();
-  nsIComboboxControlFrame *comboFrame = nsnull;
-  if (frame) {
-    frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
-  }
-
+  nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
   if (comboFrame && comboFrame->IsDroppedDown()) {
     *aState |= nsIAccessibleStates::STATE_EXPANDED;
   }
   else {
     *aState &= ~nsIAccessibleStates::STATE_FOCUSED; // Focus is on an option
     *aState |= nsIAccessibleStates::STATE_COLLAPSED;
   }
 
@@ -1155,18 +1147,17 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::
 {
   if (aIndex != nsHTMLComboboxAccessible::eAction_Click) {
     return NS_ERROR_INVALID_ARG;
   }
   nsIFrame *frame = GetFrame();
   if (!frame) {
     return NS_ERROR_FAILURE;
   }
-  nsIComboboxControlFrame *comboFrame = nsnull;
-  frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
+  nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
   if (!comboFrame) {
     return NS_ERROR_FAILURE;
   }
   // Reverse whether it's dropped down or not
   comboFrame->ShowDropDown(!comboFrame->IsDroppedDown());
 
   return NS_OK;
 }
@@ -1181,18 +1172,17 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::
 {
   if (aIndex != nsHTMLComboboxAccessible::eAction_Click) {
     return NS_ERROR_INVALID_ARG;
   }
   nsIFrame *frame = GetFrame();
   if (!frame) {
     return NS_ERROR_FAILURE;
   }
-  nsIComboboxControlFrame *comboFrame = nsnull;
-  frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
+  nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
   if (!comboFrame) {
     return NS_ERROR_FAILURE;
   }
   if (comboFrame->IsDroppedDown())
     aName.AssignLiteral("close"); 
   else
     aName.AssignLiteral("open"); 
 
@@ -1423,18 +1413,17 @@ nsHTMLSelectListAccessible(aDOMNode, aSh
 }
 
 nsIFrame*
 nsHTMLComboboxListAccessible::GetFrame()
 {
   nsIFrame* frame = nsHTMLSelectListAccessible::GetFrame();
 
   if (frame) {
-    nsIComboboxControlFrame* comboBox;
-    CallQueryInterface(frame, &comboBox);
+    nsIComboboxControlFrame* comboBox = do_QueryFrame(frame);
     if (comboBox) {
       return comboBox->GetDropDown();
     }
   }
 
   return nsnull;
 }
 
@@ -1449,20 +1438,17 @@ nsresult
 nsHTMLComboboxListAccessible::GetStateInternal(PRUint32 *aState,
                                                PRUint32 *aExtraState)
 {
   // Get focus status from base class
   nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   nsIFrame *boundsFrame = GetBoundsFrame();
-  nsIComboboxControlFrame* comboFrame = nsnull;
-  if (boundsFrame)
-    boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
-
+  nsIComboboxControlFrame* comboFrame = do_QueryFrame(boundsFrame);
   if (comboFrame && comboFrame->IsDroppedDown())
     *aState |= nsIAccessibleStates::STATE_FLOATING;
   else
     *aState |= nsIAccessibleStates::STATE_INVISIBLE;
 
   return NS_OK;
 }
 
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -90,18 +90,17 @@ nsHTMLTableCellAccessible::GetAttributes
 
   nsCOMPtr<nsIPresShell> shell = GetPresShell();
   NS_ENSURE_STATE(shell);
   
   nsIFrame *frame = shell->GetPrimaryFrameFor(content);
   NS_ASSERTION(frame, "The frame cannot be obtaied for HTML table cell.");
   NS_ENSURE_STATE(frame);
 
-  nsITableCellLayout *cellLayout = nsnull;
-  CallQueryInterface(frame, &cellLayout);
+  nsITableCellLayout *cellLayout = do_QueryFrame(frame);
   NS_ENSURE_STATE(cellLayout);
 
   PRInt32 rowIdx = -1, cellIdx = -1;
   rv = cellLayout->GetCellIndexes(rowIdx, cellIdx);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIAccessible> childAcc(this);
 
@@ -923,17 +922,21 @@ nsHTMLTableAccessible::GetTableLayout(ns
   if (!tableContent) {
     return NS_ERROR_FAILURE; // Table shut down
   }
 
   nsCOMPtr<nsIPresShell> shell = GetPresShell();
   NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
 
   nsIFrame *frame = shell->GetPrimaryFrameFor(tableContent);
-  return frame ? CallQueryInterface(frame, aTableLayout) : NS_ERROR_FAILURE;
+  if (!frame)
+    return NS_ERROR_FAILURE;
+
+  *aTableLayout = do_QueryFrame(frame);
+  return (*aTableLayout) ? NS_OK : NS_NOINTERFACE;
 }
 
 nsresult
 nsHTMLTableAccessible::GetCellAt(PRInt32        aRowIndex,
                                  PRInt32        aColIndex,
                                  nsIDOMElement* &aCell)
 {
   PRInt32 startRowIndex = 0, startColIndex = 0,
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -154,17 +154,20 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
            tag == nsAccessibilityAtoms::h3 ||
            tag == nsAccessibilityAtoms::h4 ||
            tag == nsAccessibilityAtoms::h5 ||
            tag == nsAccessibilityAtoms::h6) {
     *aRole = nsIAccessibleRole::ROLE_HEADING;
   }
   else {
     nsIFrame *frame = GetFrame();
-    if (frame && frame->GetType() == nsAccessibilityAtoms::blockFrame) {
+    if (frame && frame->GetType() == nsAccessibilityAtoms::blockFrame &&
+        frame->GetContent()->Tag() != nsAccessibilityAtoms::input) {
+      // An html:input @type="file" is the only input that is exposed as a
+      // blockframe. It must be exposed as ROLE_TEXT_CONTAINER for JAWS.
       *aRole = nsIAccessibleRole::ROLE_PARAGRAPH;
     }
     else {
       *aRole = nsIAccessibleRole::ROLE_TEXT_CONTAINER; // In ATK this works
     }
   }
   return NS_OK;
 }
@@ -286,23 +289,23 @@ nsIntRect nsHyperTextAccessible::GetBoun
     frame->GetOffsets(startFrameTextOffset, endFrameTextOffset);
     PRInt32 frameTotalTextLength = endFrameTextOffset - startFrameTextOffset;
     PRInt32 seekLength = endContentOffset - startContentOffset;
     PRInt32 frameSubStringLength = PR_MIN(frameTotalTextLength - startContentOffsetInFrame, seekLength);
 
     // Add the point where the string starts to the frameScreenRect
     nsPoint frameTextStartPoint;
     rv = frame->GetPointFromOffset(startContentOffset, &frameTextStartPoint);
-    NS_ENSURE_SUCCESS(rv, nsRect());   
+    NS_ENSURE_SUCCESS(rv, nsIntRect());
     frameScreenRect.x += context->AppUnitsToDevPixels(frameTextStartPoint.x);
 
     // Use the point for the end offset to calculate the width
     nsPoint frameTextEndPoint;
     rv = frame->GetPointFromOffset(startContentOffset + frameSubStringLength, &frameTextEndPoint);
-    NS_ENSURE_SUCCESS(rv, nsRect());   
+    NS_ENSURE_SUCCESS(rv, nsIntRect());
     frameScreenRect.width = context->AppUnitsToDevPixels(frameTextEndPoint.x - frameTextStartPoint.x);
 
     screenRect.UnionRect(frameScreenRect, screenRect);
 
     // Get ready to loop back for next frame continuation
     startContentOffset += frameSubStringLength;
     startContentOffsetInFrame = 0;
     frame = frame->GetNextContinuation();
@@ -1341,22 +1344,22 @@ nsHyperTextAccessible::GetOffsetAtPoint(
                                                   this, &coords);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // coords are currently screen coordinates, and we need to turn them into
   // frame coordinates relative to the current accessible
   if (!frameScreenRect.Contains(coords.x, coords.y)) {
     return NS_OK;   // Not found, will return -1
   }
-  nsPoint pointInHyperText(coords.x - frameScreenRect.x,
+  nsIntPoint pxInHyperText(coords.x - frameScreenRect.x,
                            coords.y - frameScreenRect.y);
   nsPresContext *context = GetPresContext();
   NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
-  pointInHyperText.x = context->DevPixelsToAppUnits(pointInHyperText.x);
-  pointInHyperText.y = context->DevPixelsToAppUnits(pointInHyperText.y);
+  nsPoint pointInHyperText(context->DevPixelsToAppUnits(pxInHyperText.x),
+                           context->DevPixelsToAppUnits(pxInHyperText.y));
 
   // Go through the frames to check if each one has the point.
   // When one does, add up the character offsets until we have a match
 
   // We have an point in an accessible child of this, now we need to add up the
   // offsets before it to what we already have
   nsCOMPtr<nsIAccessible> accessible;
   PRInt32 offset = 0;
@@ -2039,18 +2042,17 @@ nsHyperTextAccessible::ScrollSubstringTo
                                   getter_AddRefs(endNode), &endOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsPresContext *presContext = frame->PresContext();
 
   PRBool initialScrolled = PR_FALSE;
   nsIFrame *parentFrame = frame;
   while ((parentFrame = parentFrame->GetParent())) {
-    nsIScrollableFrame *scrollableFrame = nsnull;
-    CallQueryInterface(parentFrame, &scrollableFrame);
+    nsIScrollableFrame *scrollableFrame = do_QueryFrame(parentFrame);
     if (scrollableFrame) {
       if (!initialScrolled) {
         // Scroll substring to the given point. Turn the point into percents
         // relative scrollable area to use nsCoreUtils::ScrollSubstringTo.
         nsIntRect frameRect = parentFrame->GetScreenRectExternal();
         PRInt32 devOffsetX = coords.x - frameRect.x;
         PRInt32 devOffsetY = coords.y - frameRect.y;
 
@@ -2092,17 +2094,17 @@ nsresult nsHyperTextAccessible::ContentT
   }
   NS_ASSERTION(aFrame->GetType() == nsAccessibilityAtoms::textFrame,
                "Need text frame for offset conversion");
   NS_ASSERTION(aFrame->GetPrevContinuation() == nsnull,
                "Call on primary frame only");
 
   gfxSkipChars skipChars;
   gfxSkipCharsIterator iter;
-  // Only get info up to original ofset, we know that will be larger than skipped offset
+  // Only get info up to original offset, we know that will be larger than skipped offset
   nsresult rv = aFrame->GetRenderedText(nsnull, &skipChars, &iter, 0, aContentOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 ourRenderedStart = iter.GetSkippedOffset();
   PRInt32 ourContentStart = iter.GetOriginalOffset();
 
   *aRenderedOffset = iter.ConvertOriginalToSkipped(aContentOffset + ourContentStart) -
                     ourRenderedStart;
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -211,18 +211,17 @@ STDMETHODIMP nsAccessibleWrap::get_accPa
           // we want the native accessible for that outer window
           hwnd = ::GetParent(hwnd);
           NS_ASSERTION(hwnd, "No window handle for window");
         }
       }
       else {
         // If a frame is a scrollable frame, then it has one window for the client area,
         // not an extra parent window for just the scrollbars
-        nsIScrollableFrame *scrollFrame = nsnull;
-        CallQueryInterface(frame, &scrollFrame);
+        nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
         if (scrollFrame) {
           hwnd = (HWND)scrollFrame->GetScrolledFrame()->GetWindow()->GetNativeData(NS_NATIVE_WINDOW);
           NS_ASSERTION(hwnd, "No window handle for window");
         }
       }
     }
 
     if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
@@ -1912,17 +1911,17 @@ void nsAccessibleWrap::UpdateSystemCaret
   }
 
   nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
   if (!caretAccessible) {
     return;
   }
 
   nsIWidget *widget;
-  nsRect caretRect = caretAccessible->GetCaretRect(&widget);        
+  nsIntRect caretRect = caretAccessible->GetCaretRect(&widget);
   HWND caretWnd; 
   if (caretRect.IsEmpty() || !(caretWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW))) {
     return;
   }
 
   // Create invisible bitmap for caret, otherwise its appearance interferes
   // with Gecko caret
   HBITMAP caretBitMap = CreateBitmap(1, caretRect.height, 1, 1, NULL);
--- a/accessible/src/msaa/nsTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsTextAccessibleWrap.cpp
@@ -122,19 +122,19 @@ STDMETHODIMP nsTextAccessibleWrap::get_c
   }
 
   nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
   nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(docAccessible));
   NS_ASSERTION(accessible, "There must always be a doc accessible, but there isn't");
 
   accessible->GetBounds(&docX, &docY, &docWidth, &docHeight);
 
-  nsRect unclippedRect(x, y, width, height);
-  nsRect docRect(docX, docY, docWidth, docHeight);
-  nsRect clippedRect;
+  nsIntRect unclippedRect(x, y, width, height);
+  nsIntRect docRect(docX, docY, docWidth, docHeight);
+  nsIntRect clippedRect;
 
   clippedRect.IntersectRect(unclippedRect, docRect);
 
   *aX = clippedRect.x;
   *aY = clippedRect.y;
   *aWidth = clippedRect.width;
   *aHeight = clippedRect.height;
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@@ -217,21 +217,21 @@ nsresult nsTextAccessibleWrap::GetCharac
   
   nsPoint startPoint, endPoint;
   nsIFrame *startFrame = GetPointFromOffset(frame, aStartOffset, PR_TRUE, startPoint);
   nsIFrame *endFrame = GetPointFromOffset(frame, aEndOffset, PR_FALSE, endPoint);
   if (!startFrame || !endFrame) {
     return E_FAIL;
   }
   
-  nsRect sum(0, 0, 0, 0);
+  nsIntRect sum(0, 0, 0, 0);
   nsIFrame *iter = startFrame;
   nsIFrame *stopLoopFrame = endFrame->GetNextContinuation();
   for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) {
-    nsRect rect = iter->GetScreenRectExternal();
+    nsIntRect rect = iter->GetScreenRectExternal();
     nscoord start = (iter == startFrame) ? presContext->AppUnitsToDevPixels(startPoint.x) : 0;
     nscoord end = (iter == endFrame) ? presContext->AppUnitsToDevPixels(endPoint.x) :
                                        rect.width;
     rect.x += start;
     rect.width = end - start;
     sum.UnionRect(sum, rect);
   }
 
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -240,33 +240,16 @@ nsXFormsAccessible::GetDescription(nsASt
     aDescription = description;
     return NS_OK;
   }
 
   // search the xforms:hint element
   return GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
 }
 
-nsresult
-nsXFormsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
-{
-  NS_ENSURE_ARG_POINTER(aAttributes);
-
-  nsresult rv = nsHyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString name;
-  rv = sXFormsService->GetBuiltinTypeName(mDOMNode, name);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString unused;
-  return aAttributes->SetStringProperty(NS_LITERAL_CSTRING("datatype"),
-                                        name, unused);
-}
-
 NS_IMETHODIMP
 nsXFormsAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
 {
   NS_ENSURE_ARG_POINTER(aAllowsAnonChildren);
 
   *aAllowsAnonChildren = PR_FALSE;
   return NS_OK;
 }
--- a/accessible/src/xforms/nsXFormsAccessible.h
+++ b/accessible/src/xforms/nsXFormsAccessible.h
@@ -84,20 +84,16 @@ public:
 
   // Returns value of child xforms 'label' element.
   virtual nsresult GetNameInternal(nsAString& aName);
 
   // Returns state of xforms element taking into account state of instance node
   // that it is bound to.
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
-  // Appends ARIA 'datatype' property based on datatype of instance node that
-  // element is bound to.
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
-
   // Denies accessible nodes in anonymous content of xforms element by
   // always returning PR_FALSE value.
   NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
 
 protected:
   // Returns value of first child xforms element by tagname that is bound to
   // instance node.
   nsresult GetBoundChildElementValue(const nsAString& aTagName,
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -55,23 +55,26 @@ include $(topsrcdir)/config/rules.mk
 		nsIAccessible_name.js \
 		nsIAccessible_name.xbl \
  		nsIAccessible_selects.js \
 		nsIAccessible_states.js \
 		nsIAccessibleEditableText.js \
 		test_aria_activedescendant.html \
 		test_aria_role_article.html \
 		test_aria_role_equation.html \
+		test_aria_token_attrs.html \
 		$(warning test_bug368835.xul temporarily disabled) \
 		test_bug420863.html \
 		test_cssattrs.html \
 		test_events_caretmove.html \
+		test_events_mutation.html \
 		test_groupattrs.xul \
 		test_groupattrs.html \
 	$(warning test_table_indexes.html temporarily disabled) \
+		test_nsHyperTextAcc_roles.html \
 		test_nsIAccessible_actions.html \
 		$(warning test_nsIAccessible_actions.xul temporarily disabled) \
 		test_nsIAccessible_applicationAccessible.html \
 		test_nsIAccessible_comboboxes.xul \
 		test_nsIAccessible_editablebody.html \
 		test_nsIAccessible_editabledoc.html \
 		test_nsIAccessible_name.html \
 		test_nsIAccessible_name_button.html \
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -34,38 +34,45 @@ const nsIAccessibleValue = Components.in
 const nsIObserverService = Components.interfaces.nsIObserverService;
 
 const nsIDOMNode = Components.interfaces.nsIDOMNode;
 const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Roles
 
+const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
 const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
 const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION;
 const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
 const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
 const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
+const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
 const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
+const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
 const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
+const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
 
 ////////////////////////////////////////////////////////////////////////////////
 // States
 
+const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED;
+const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE;
 const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
 const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED;
 const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
 const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
 const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
 const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
 const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
+const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
 const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
 const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
 const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
 
 const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
 const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
 const EXT_STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
 const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
@@ -98,17 +105,17 @@ function addA11yLoadEvent(aFunc)
         var accDoc = getAccessible(document);
         var state = {};
         accDoc.getState(state, {});
         if (state.value & nsIAccessibleStates.STATE_BUSY)
           return waitForDocLoad();
 
         aFunc.call();
       },
-      0
+      200
     );
   }
 
   addLoadEvent(waitForDocLoad);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Get DOM node/accesible helpers
@@ -216,124 +223,185 @@ function getAccessible(aAccOrElmOrID, aI
  *                       available constants).
  * @param aEventHandler  event listener object, when accessible event of the
  *                       given type is handled then 'handleEvent' method of
  *                       this object is invoked with nsIAccessibleEvent object
  *                       as the first argument.
  */
 function registerA11yEventListener(aEventType, aEventHandler)
 {
-  if (!gA11yEventListenersCount) {
-    gObserverService = Components.classes["@mozilla.org/observer-service;1"].
-      getService(nsIObserverService);
+  listenA11yEvents(true);
 
-    gObserverService.addObserver(gA11yEventObserver, "accessible-event",
-                                 false);
-  }
-
-  if (!(aEventType in gA11yEventListeners))
-    gA11yEventListeners[aEventType] = new Array();
-
-  gA11yEventListeners[aEventType].push(aEventHandler);
-  gA11yEventListenersCount++;
+  gA11yEventApplicantsCount++;
+  addA11yEventListener(aEventType, aEventHandler);
 }
 
 /**
  * Unregister accessibility event listener. Must be called for every registered
- * event listener (see registerA11yEventListener() function) when it's not
- * needed.
+ * event listener (see registerA11yEventListener() function) when the listener
+ * is not needed.
  */
 function unregisterA11yEventListener(aEventType, aEventHandler)
 {
-  var listenersArray = gA11yEventListeners[aEventType];
-  if (listenersArray) {
-    var index = listenersArray.indexOf(aEventHandler);
-    listenersArray.splice(index, 1);
+  removeA11yEventListener(aEventType, aEventHandler);
 
-    if (!listenersArray.length) {
-      gA11yEventListeners[aEventType] = null;
-      delete gA11yEventListeners[aEventType];
-    }
-  }
-  
-  gA11yEventListenersCount--;
-  if (!gA11yEventListenersCount) {
-    gObserverService.removeObserver(gA11yEventObserver,
-                                    "accessible-event");
-  }
+  gA11yEventApplicantsCount--;
+  listenA11yEvents(false);
 }
 
 /**
  * Creates event queue for the given event type. The queue consists of invoker
  * objects, each of them generates the event of the event type. When queue is
  * started then every invoker object is asked to generate event after timeout.
  * When event is caught then current invoker object is asked to check wether
  * event was handled correctly.
  *
  * Invoker interface is:
+ *
  *   var invoker = {
- *     invoke: function(){}, // generates event for the DOM node
- *     check: function(aEvent){}, // checks event for correctness
- *     DOMNode getter() {} // DOM node event is generated for
+ *     // Generates accessible event or event sequence.
+ *     invoke: function(){},
+ *
+ *     // Invoker's check of handled event for correctness [optional].
+ *     check: function(aEvent){},
+ *
+ *     // Is called when event of registered type is handled.
+ *     debugCheck: function(aEvent){},
+ *
+ *     // DOM node event is generated for (the case when invoker generates
+ *     // single event, see 'eventSeq' property).
+ *     DOMNode getter() {},
+ *
+ *     // Array of items defining handled events. Every item is array with two
+ *     // elements, first element is event type, second element is event target
+ *     // (DOM node).
+ *     eventSeq getter() {},
+ *
+ *     // The ID of invoker.
  *     getID: function(){} // returns invoker ID
  *   };
  *
- * @param  aEventType     the given event type
+ * @param  aEventType     [optional] the default event type (isn't used if
+ *                        invoker defines eventSeq property).
  */
 function eventQueue(aEventType)
 {
+  // public
+
   /**
    * Add invoker object into queue.
    */
   this.push = function eventQueue_push(aEventInvoker)
   {
     this.mInvokers.push(aEventInvoker);
   }
 
   /**
    * Start the queue processing.
    */
   this.invoke = function eventQueue_invoke()
   {
-    window.setTimeout(
-      function(aQueue)
-      {
-        if (aQueue.mIndex == aQueue.mInvokers.length - 1) {
-          unregisterA11yEventListener(aQueue.mEventType, aQueue.mEventHandler);
+    listenA11yEvents(true);
+    gA11yEventApplicantsCount++;
+
+    window.setTimeout(function(aQueue) { aQueue.processInvoker(); }, 200, this);
+  }
+
+  // private
+
+  this.processInvoker = function eventQueue_processInvoker()
+  {
+    this.clearEventHandler();
+      
+    if (this.mIndex == this.mInvokers.length - 1) {
+
+      gA11yEventApplicantsCount--;
+      listenA11yEvents(false);
 
-          for (var idx = 0; idx < aQueue.mInvokers.length; idx++) {
-            var invoker = aQueue.mInvokers[idx];
-            ok(invoker.wasCaught,
-               "test with ID = '" + invoker.getID() + "' failed.");
+      for (var idx = 0; idx < this.mInvokers.length; idx++) {
+        var invoker = this.mInvokers[idx];
+        var id = invoker.getID();
+
+        if (invoker.wasCaught) {
+          for (var jdx = 0; jdx < invoker.wasCaught.length; jdx++) {
+            var seq = this.getEventSequence(invoker);
+            var type = seq[jdx][0];
+            var typeStr = gAccRetrieval.getStringEventType(type);
+
+            var msg = "test with ID = '" + id + "' failed. ";
+            if (invoker.doNotExpectEvents) {
+              ok(!invoker.wasCaught[jdx],
+                 msg + "There is unexpected " + typeStr + " event.");
+            } else {
+              ok(invoker.wasCaught[jdx],
+                 msg + "No " + typeStr + " event.");
+            }
           }
-
-          SimpleTest.finish();
-          return;
+        } else {
+          ok(false,
+             "test with ID = '" + id + "' failed. No events were registered.");
         }
+      }
 
-        aQueue.mInvokers[++aQueue.mIndex].invoke();
+      SimpleTest.finish();
+      return;
+    }
 
-        aQueue.invoke();
-      },
-      200, this
-    );
+    this.mIndex++;
+    this.setEventHandler();
+
+    this.mInvokers[this.mIndex].invoke();
+
+    window.setTimeout(function(aQueue) { aQueue.processInvoker(); }, 200, this);
   }
 
   this.getInvoker = function eventQueue_getInvoker()
   {
     return this.mInvokers[this.mIndex];
   }
 
-  this.mEventType = aEventType;
+  this.getEventSequence = function eventQueue_getEventSeq(aInvoker)
+  {
+    if (!aInvoker) // no invoker, return cached event sequence
+      return this.mEventSeq;
+
+    return ("eventSeq" in aInvoker) ?
+      aInvoker.eventSeq : [[this.mDefEventType, aInvoker.DOMNode]];
+  }
+
+  this.setEventHandler = function eventQueue_setEventHandler()
+  {
+    var invoker = this.getInvoker();
+    this.mEventSeq = this.getEventSequence(invoker);
+
+    if (this.mEventSeq) {
+      invoker.wasCaught = new Array(this.mEventSeq.length);
+
+      for (var idx = 0; idx < this.mEventSeq.length; idx++)
+        addA11yEventListener(this.mEventSeq[idx][0], this.mEventHandler);
+    }
+  }
+
+  this.clearEventHandler = function eventQueue_clearEventHandler()
+  {
+    if (this.mEventSeq) {
+      for (var idx = 0; idx < this.mEventSeq.length; idx++)
+        removeA11yEventListener(this.mEventSeq[idx][0], this.mEventHandler);
+
+      this.mEventSeq = null;
+    }
+  }
+
+  this.mDefEventType = aEventType;
   this.mEventHandler = new eventHandlerForEventQueue(this);
 
-  registerA11yEventListener(this.mEventType, this.mEventHandler);
-
   this.mInvokers = new Array();
   this.mIndex = -1;
+
+  this.mEventSeq = null;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible general
@@ -347,47 +415,133 @@ function initialize()
 addLoadEvent(initialize);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible Events
 
 var gObserverService = null;
 
 var gA11yEventListeners = {};
-var gA11yEventListenersCount = 0;
+var gA11yEventApplicantsCount = 0;
+var gA11yEventDumpID = ""; // set up this variable to dump events into DOM.
 
 var gA11yEventObserver =
 {
   observe: function observe(aSubject, aTopic, aData)
   {
     if (aTopic != "accessible-event")
       return;
 
     var event = aSubject.QueryInterface(nsIAccessibleEvent);
     var listenersArray = gA11yEventListeners[event.eventType];
+
+    if (gA11yEventDumpID) { // debug stuff
+      var type = gAccRetrieval.getStringEventType(event.eventType);
+      var target = event.DOMNode;
+
+      var info = "event type: " + type + ", target: " + target.localName;
+      if (listenersArray)
+        info += ", registered listeners count is " + listenersArray.length;
+
+      var div = document.createElement("div");      
+      div.textContent = info;
+
+      var dumpElm = document.getElementById(gA11yEventDumpID);
+      dumpElm.appendChild(div);
+    }
+
     if (!listenersArray)
       return;
 
     for (var index = 0; index < listenersArray.length; index++)
       listenersArray[index].handleEvent(event);
   }
 };
 
+function listenA11yEvents(aStartToListen)
+{
+  if (aStartToListen && !gObserverService) {
+    gObserverService = Components.classes["@mozilla.org/observer-service;1"].
+      getService(nsIObserverService);
+    
+    gObserverService.addObserver(gA11yEventObserver, "accessible-event",
+                                 false);
+  } else if (!gA11yEventApplicantsCount) {
+    gObserverService.removeObserver(gA11yEventObserver,
+                                    "accessible-event");
+    gObserverService = null;
+  }
+}
+
+function addA11yEventListener(aEventType, aEventHandler)
+{
+  if (!(aEventType in gA11yEventListeners))
+    gA11yEventListeners[aEventType] = new Array();
+  
+  gA11yEventListeners[aEventType].push(aEventHandler);
+}
+
+function removeA11yEventListener(aEventType, aEventHandler)
+{
+  var listenersArray = gA11yEventListeners[aEventType];
+  if (!listenersArray)
+    return false;
+
+  var index = listenersArray.indexOf(aEventHandler);
+  if (index == -1)
+    return false;
+
+  listenersArray.splice(index, 1);
+  
+  if (!listenersArray.length) {
+    gA11yEventListeners[aEventType] = null;
+    delete gA11yEventListeners[aEventType];
+  }
+
+  return true;
+}
+
 function eventHandlerForEventQueue(aQueue)
 {
   this.handleEvent = function eventHandlerForEventQueue_handleEvent(aEvent)
   {
     var invoker = this.mQueue.getInvoker();
-    if (!invoker) // skip events before test was started
+    var eventSeq = this.mQueue.getEventSequence();
+
+    if (!invoker && !eventSeq) // skip events before test was started
       return;
 
+    if (eventSeq != this.mEventSeq) {
+      this.mEventSeqIdx = -1;
+      this.mEventSeq = eventSeq;
+    }
+
     if ("debugCheck" in invoker)
       invoker.debugCheck(aEvent);
 
-    if (aEvent.DOMNode == invoker.DOMNode) {
-      invoker.check(aEvent);
-      invoker.wasCaught = true;
+    if (invoker.doNotExpectEvents) {
+      // Search through event sequence to ensure it doesn't containt handled
+      // event.
+      for (var idx = 0; idx < this.mEventSeq.length; idx++) {
+        if (aEvent.eventType == eventSeq[idx][0] &&
+            aEvent.DOMNode == eventSeq[idx][1]) {
+          invoker.wasCaught[idx] = true;
+        }
+      }
+    } else {
+      // We wait for events in order specified by evenSeq variable.
+      var idx = this.mEventSeqIdx + 1;
+
+      if (aEvent.eventType == eventSeq[idx][0] &&
+          aEvent.DOMNode == eventSeq[idx][1]) {
+        if ("check" in invoker)
+          invoker.check(aEvent);
+
+        invoker.wasCaught[idx] = true;
+        this.mEventSeqIdx++;
+      }
     }
   }
-  
+
   this.mQueue = aQueue;
+  this.mEventSeq = null;
+  this.mEventSeqIdx = -1;
 }
-
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_aria_token_attrs.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=452388
+-->
+<head>
+  <title>An NMTOKEN based ARIA property is undefined if the ARIA attribute is not present, or is set to "" or "undefined"</title>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+  <script type="application/javascript"
+      src="chrome://mochikit/content/a11y/accessible/nsIAccessible_states.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+       // test (treeitem) selectable and selected states
+      testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
+      testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
+      testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
+      testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
+      testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
+
+      // test (menuitem) checkable and checked states
+      testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
+
+      // test (checkbox) checkable and checked states
+      testStates("checkbox_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("checkbox_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("checkbox_checked_empty", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("checkbox_checked_undefined", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("checkbox_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
+
+      // test native checkbox checked state and aria-checked state (if conflict, native wins)
+      testStates("native_checkbox_nativechecked_ariatrue", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("native_checkbox_nativechecked_ariafalse", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("native_checkbox_nativechecked_ariaempty", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("native_checkbox_nativechecked_ariaundefined", (STATE_CHECKABLE | STATE_CHECKED));
+      testStates("native_checkbox_nativechecked_ariaabsent", (STATE_CHECKABLE | STATE_CHECKED));
+      
+      testStates("native_checkbox_nativeunchecked_ariatrue", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("native_checkbox_nativeunchecked_ariafalse", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("native_checkbox_nativeunchecked_ariaempty", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("native_checkbox_nativeunchecked_ariaundefined", STATE_CHECKABLE, 0, STATE_CHECKED);
+      testStates("native_checkbox_nativeunchecked_ariaabsent", STATE_CHECKABLE, 0, STATE_CHECKED);
+
+      // test button aria-pressed states
+      testStates("button_pressed_true", STATE_PRESSED);
+      testStates("button_pressed_false", 0, 0, STATE_PRESSED);
+      testStates("button_pressed_empty", 0, 0, STATE_PRESSED);
+      testStates("button_pressed_undefined", 0, 0, STATE_PRESSED);
+      testStates("button_pressed_absent", 0, 0, STATE_PRESSED);
+      
+      // test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
+      var aButton = getAccessible("button_pressed_true");
+      if (aButton)
+        is(aButton.finalRole, ROLE_TOGGLE_BUTTON, "Wrong role for togglebutton!");
+      aButton = getAccessible("button_pressed_false");
+      if (aButton)
+        is(aButton.finalRole, ROLE_TOGGLE_BUTTON, "Wrong role for togglebutton!");
+      aButton = getAccessible("button_pressed_empty");
+      if (aButton)
+        is(aButton.finalRole, ROLE_PUSHBUTTON, "Wrong role for button!");
+      aButton = getAccessible("button_pressed_undefined");
+      if (aButton)
+        is(aButton.finalRole, ROLE_PUSHBUTTON, "Wrong role for button!");
+      aButton = getAccessible("button_pressed_absent");
+      if (aButton)
+        is(aButton.finalRole, ROLE_PUSHBUTTON, "Wrong role for button!");
+      
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">Mozilla Bug 452388</a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
+  <div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
+  <div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
+  <div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
+  <div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
+
+  <div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
+  <div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
+  <div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
+  <div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
+  <div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
+  
+  <div id="checkbox_checked_true" role="checkbox" aria-checked="true">This checkbox has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
+  <div id="checkbox_checked_false" role="checkbox" aria-checked="false">This checkbox has aria-checked="false" and should get STATE_CHECKABLE.</div>
+  <div id="checkbox_checked_empty" role="checkbox" aria-checked="">This checkbox has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
+  <div id="checkbox_checked_undefined" role="checkbox" aria-checked="undefined">This checkbox has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
+  <div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
+
+  <form action="">
+    <input id="native_checkbox_nativechecked_ariatrue" type="checkbox" checked="checked" aria-checked="true"/>
+    <input id="native_checkbox_nativechecked_ariafalse" type="checkbox" checked="checked" aria-checked="false"/>
+    <input id="native_checkbox_nativechecked_ariaempty" type="checkbox" checked="checked" aria-checked=""/>
+    <input id="native_checkbox_nativechecked_ariaundefined" type="checkbox" checked="checked" aria-checked="undefined"/>
+    <input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked" aria-checked="false"/>
+
+    <input id="native_checkbox_nativeunchecked_ariatrue" type="checkbox" aria-checked="true"/>
+    <input id="native_checkbox_nativeunchecked_ariafalse" type="checkbox" aria-checked="false"/>
+    <input id="native_checkbox_nativeunchecked_ariaempty" type="checkbox" aria-checked=""/>
+    <input id="native_checkbox_nativeunchecked_ariaundefined" type="checkbox" aria-checked="undefined"/>
+    <input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox" aria-checked="false"/>
+  </form>
+  
+  <div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
+  <div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
+  <div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
+  <div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
+  <div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
+ 
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_events_mutation.html
@@ -0,0 +1,272 @@
+<html>
+
+<head>
+  <title>Accessible mutation events testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <style>
+    div.displayNone a { display:none; }
+    div.visibilityHidden a { visibility:hidden; }
+</style>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+
+  <script type="application/javascript">
+    /**
+     * Invokers.
+     */
+    var kNoEvents = 0;
+
+    var kShowEvent = 1;
+    var kHideEvent = 2;
+    var kReorderEvent = 4;
+    var kShowEvents = kShowEvent | kReorderEvent;
+    var kHideEvents = kHideEvent | kReorderEvent;
+    var kHideAndShowEvents = kHideEvents | kShowEvent;
+
+    function mutateA11yTree(aNodeOrID, aEventTypes, aDoNotExpectEvents,
+                            aIsDOMChange)
+    {
+      this.DOMNode = getNode(aNodeOrID);
+
+      this.eventSeq = [];
+
+      if (aIsDOMChange) {
+        if (aEventTypes & kHideEvent)
+          this.eventSeq.push([nsIAccessibleEvent.EVENT_DOM_DESTROY,
+                              this.DOMNode]);
+
+        if (aEventTypes & kShowEvent)
+          this.eventSeq.push([nsIAccessibleEvent.EVENT_DOM_CREATE,
+                              this.DOMNode]);
+      } else {
+        if (aEventTypes & kHideEvent)
+          this.eventSeq.push([nsIAccessibleEvent.EVENT_ASYNCH_HIDE,
+                              this.DOMNode]);
+
+        if (aEventTypes & kShowEvent)
+          this.eventSeq.push([nsIAccessibleEvent.EVENT_ASYNCH_SHOW,
+                              this.DOMNode]);
+      }
+
+      if (aEventTypes & kReorderEvent)
+        this.eventSeq.push([nsIAccessibleEvent.EVENT_REORDER,
+                            this.DOMNode.parentNode]);
+
+      this.doNotExpectEvents = aDoNotExpectEvents;
+    }
+
+    function changeStyle(aNodeOrID, aProp, aValue, aEventTypes)
+    {
+      this.__proto__ = new mutateA11yTree(aNodeOrID, aEventTypes, false, false);
+
+      this.invoke = function changeStyle_invoke()
+      {
+        this.DOMNode.style[aProp] = aValue;
+      }
+
+      this.getID = function changeStyle_getID()
+      {
+        return aNodeOrID + " change style " + aProp + " on value " + aValue;
+      }
+    }
+
+    function changeClass(aParentNodeOrID, aNodeOrID, aClassName, aEventTypes)
+    {
+      this.__proto__ = new mutateA11yTree(aNodeOrID, aEventTypes, false, false);
+
+      this.invoke = function changeClass_invoke()
+      {
+        this.parentDOMNode.className = aClassName;
+      }
+
+      this.getID = function changeClass_getID()
+      {
+        return aNodeOrID + " change class " + aClassName;
+      }
+
+      this.parentDOMNode = getNode(aParentNodeOrID);
+    }
+
+    function cloneAndAppendToDOM(aNodeOrID, aEventTypes)
+    {
+      var eventTypes = aEventTypes || kShowEvents;
+      var doNotExpectEvents = (aEventTypes == kNoEvents);
+
+      this.__proto__ = new mutateA11yTree(aNodeOrID, eventTypes,
+                                          doNotExpectEvents, true);
+
+      this.invoke = function cloneAndAppendToDOM_invoke()
+      {
+        var newElm = this.DOMNode.cloneNode(true);
+        newElm.removeAttribute('id');
+        this.eventSeq[0][1] = newElm;
+        this.DOMNode.parentNode.appendChild(newElm);
+      }
+
+      this.getID = function cloneAndAppendToDOM_getID()
+      {
+        return aNodeOrID + " clone and append to DOM.";
+      }
+    }
+
+    function removeFromDOM(aNodeOrID, aEventTypes)
+    {
+      var eventTypes = aEventTypes || kHideEvents;
+      var doNotExpectEvents = (aEventTypes == kNoEvents);
+
+      this.__proto__ = new mutateA11yTree(aNodeOrID, eventTypes,
+                                          doNotExpectEvents, true);
+
+      this.invoke = function removeFromDOM_invoke()
+      {
+        this.DOMNode.parentNode.removeChild(this.DOMNode);
+      }
+
+      this.getID = function removeFromDOM_getID()
+      {
+        return aNodeOrID + " remove from DOM.";
+      }
+    }
+
+    function cloneAndReplaceInDOM(aNodeOrID)
+    {
+      this.__proto__ = new mutateA11yTree(aNodeOrID, kHideAndShowEvents,
+                                          false, true);
+
+      this.invoke = function cloneAndReplaceInDOM_invoke()
+      {
+        var newElm = this.DOMNode.cloneNode(true);
+        newElm.removeAttribute('id');
+        this.eventSeq[1][1] = newElm;
+        this.DOMNode.parentNode.replaceChild(newElm, this.DOMNode);
+      }
+
+      this.getID = function cloneAndReplaceInDOM_getID()
+      {
+        return aNodeOrID + " clone and replace in DOM.";
+      }
+    }
+
+    /**
+     * Do tests.
+     */
+    var gQueue = null;
+    // var gA11yEventDumpID = "eventdump"; // debug stuff
+
+    function doTests()
+    {
+      gQueue = new eventQueue();
+
+      // Show/hide events by changing of display style of accessible DOM node
+      // from 'inline' to 'none', 'none' to 'inline'.
+      var id = "link1";
+      getAccessible(id); // ensure accessible is created
+      gQueue.push(new changeStyle(id, "display", "none", kHideEvents));
+
+      // XXX: bug 472662 - there is no expected reorder event
+      gQueue.push(new changeStyle(id, "display", "inline", kShowEvent));
+
+      // Show/hide events by changing of visibility style of accessible DOM node
+      // from 'visible' to 'hidden', 'hidden' to 'visible'.
+      var id = "link2";
+      getAccessible(id);
+      gQueue.push(new changeStyle(id, "visibility", "hidden", kHideEvents));
+      gQueue.push(new changeStyle(id, "visibility", "visible", kShowEvents));
+
+      // Show/hide events by changing of display style of accessible DOM node
+      // from 'inline' to 'block', 'block' to 'inline'.
+      var id = "link3";
+      getAccessible(id); // ensure accessible is created
+      gQueue.push(new changeStyle(id, "display", "block", kHideAndShowEvents));
+      gQueue.push(new changeStyle(id, "display", "inline", kHideAndShowEvents));
+
+      // Show/hide events by changing of visibility style of accessible DOM node
+      // from 'collapse' to 'visible', 'visible' to 'collapse'.
+      var id = "link4";
+      gQueue.push(new changeStyle(id, "visibility", "visible", kShowEvents));
+      gQueue.push(new changeStyle(id, "visibility", "collapse", kHideEvents));
+
+      // Show/hide events by adding new accessible DOM node and removing old one.
+      var id = "link5";
+      // XXX: bug 472662 - there is no expected reorder event
+      gQueue.push(new cloneAndAppendToDOM(id, kShowEvent));
+      gQueue.push(new removeFromDOM(id));
+
+      // No show/hide events by adding new not accessible DOM node and removing
+      // old one, no reorder event for their parent.
+      var id = "child1";
+      gQueue.push(new cloneAndAppendToDOM(id, kNoEvents));
+      gQueue.push(new removeFromDOM(id, kNoEvents));
+
+      // Show/hide events by adding new accessible DOM node and removing
+      // old one, there is reorder event for their parent.
+      var id = "child2";
+      gQueue.push(new cloneAndAppendToDOM(id, kShowEvent));
+      gQueue.push(new removeFromDOM(id));
+
+      // Show/hide events by creating new accessible DOM node and replacing
+      // old one.
+      // XXX: bug 472810
+      // gQueue.push(new cloneAndReplaceInDOM("link6"));
+
+      // Show/hide events by changing class name on the parent node.
+      // XXX: bug 472662 - there is no expected reorder event
+      gQueue.push(new changeClass("container2", "link7", "", kShowEvent));
+      gQueue.push(new changeClass("container2", "link7", "displayNone",
+                                  kHideEvents));
+      gQueue.push(new changeClass("container3", "link8", "", kShowEvents));
+      gQueue.push(new changeClass("container3", "link8", "visibilityHidden",
+                                  kHideEvents));
+
+      gQueue.invoke(); // Will call SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=469985"
+     title=" turn the test from bug 354745 into mochitest">
+    Mozilla Bug 469985
+  </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=472662"
+     title="no reorder event when html:link display property is changed from 'none' to 'inline'">
+    Mozilla Bug 472662
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <div id="eventdump"/>
+
+  <a id="link1" href="http://www.google.com">Link #1</a>
+  <a id="link2" href="http://www.google.com">Link #2</a>
+  <a id="link3" href="http://www.google.com">Link #3</a>
+  <a id="link4" href="http://www.google.com" style="visibility:collapse">Link #4</a>
+  <a id="link5" href="http://www.google.com">Link #5</a>
+
+  <div id="container" role="list"><span id="child1"></span><span id="child2" role="listitem"></span></div>
+
+  <a id="link6" href="http://www.google.com">Link #6</a>
+
+  <div id="container2" class="displayNone"><a id="link7">Link #7</a></div>
+  <div id="container3" class="visibilityHidden"><a id="link8">Link #8</a></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_nsHyperTextAcc_roles.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=472326
+-->
+<head>
+  <title>test nsHyperTextAccessible roles</title>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+
+  <script type="application/javascript">
+    function doTests()
+    {
+      // Test that an html:input @type="file" is exposed as ROLE_TEXT_CONTAINER.
+      // After fix for bug 471356, it was temporarily exposed as a paragraph,
+      // breaking JAWS compatibility.
+      fileUploadAcc = getAccessible("data");
+      if (fileUploadAcc)
+        is(fileUploadAcc.role, ROLE_TEXT_CONTAINER,
+           "Wrong role for file upload textbox!");
+
+      // Test regular paragraph by comparison to make sure exposure does not
+      // get broken.
+      var paraAcc = getAccessible("p");
+      if (paraAcc)
+        is(paraAcc.role, ROLE_PARAGRAPH, "Wrong role for paragraph!");
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTests);
+  </script>
+</head>
+<body>
+
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=472326"
+     title="html:input of type "file" no longer rendered to screen readers">
+     Mozilla Bug 472326
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <form action="submit.php" method="post">
+    <label for="data">File</label>:
+    <input type="file" id="data" name="data" size="50"/>
+  </form>
+  <p id="p">A paragraph for comparison.</p>
+</body>
+</html>
--- a/accessible/tests/mochitest/test_nsIAccessible_comboboxes.xul
+++ b/accessible/tests/mochitest/test_nsIAccessible_comboboxes.xul
@@ -70,17 +70,17 @@
     function getBrowser()
     {
       return {
         mCurrentBrowser: { engines: new Array() }
       };
     }
 
     SimpleTest.waitForExplicitFinish();
-    addLoadEvent(doTest);
+    addA11yLoadEvent(doTest);
   ]]>
   </script>
 
   <hbox style="overflow: auto;" flex="1">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=467057"
          title="xul menulist doesn't fire expand/collapse state change events">
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -410,17 +410,17 @@ pref("privacy.item.sessions",    true);
 pref("privacy.item.offlineApps", false);
 
 // What default should we use for the time span in the sanitizer:
 // 0 - Clear everything
 // 1 - Last Hour
 // 2 - Last 2 Hours
 // 3 - Last 4 Hours
 // 4 - Today
-pref("privacy.sanitize.timeSpan", 0);
+pref("privacy.sanitize.timeSpan", 1);
 pref("privacy.sanitize.sanitizeOnShutdown", false);
 
 pref("network.proxy.share_proxy_settings",  false); // use the same proxy settings for all protocols
 
 pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
 
 // l12n and i18n
 pref("intl.accept_languages", "chrome://global/locale/intl.properties");
--- a/browser/base/content/browser-textZoom.js
+++ b/browser/base/content/browser-textZoom.js
@@ -221,20 +221,20 @@ var FullZoom = {
       // the global preference has changed.
       if (!this._cps.hasPref(gBrowser.currentURI, this.name))
         this._applyPrefToSetting();
     }
   },
 
   // location change observer
 
-  onLocationChange: function FullZoom_onLocationChange(aURI) {
+  onLocationChange: function FullZoom_onLocationChange(aURI, aBrowser) {
     if (!aURI)
       return;
-    this._applyPrefToSetting(this._cps.getPref(aURI, this.name));
+    this._applyPrefToSetting(this._cps.getPref(aURI, this.name), aBrowser);
   },
 
   // update state of zoom type menu item
 
   updateMenu: function FullZoom_updateMenu() {
     var menuItem = document.getElementById("toggle_zoom");
 
     menuItem.setAttribute("checked", !ZoomManager.useFullZoom);
@@ -281,28 +281,28 @@ var FullZoom = {
    * those child text zooms should get updated when the parent zoom gets set,
    * and perhaps the same is true for full zoom
    * (although DocumentViewerImpl::SetFullZoom doesn't mention it).
    *
    * So when we apply new zoom values to the browser, we simply set the zoom.
    * We don't check first to see if the new value is the same as the current
    * one.
    **/
-  _applyPrefToSetting: function FullZoom__applyPrefToSetting(aValue) {
+  _applyPrefToSetting: function FullZoom__applyPrefToSetting(aValue, aBrowser) {
     if (!this.siteSpecific || gInPrintPreviewMode ||
         content.document instanceof Ci.nsIImageDocument)
       return;
 
     try {
       if (typeof aValue != "undefined")
-        ZoomManager.zoom = this._ensureValid(aValue);
+        ZoomManager.setZoomForBrowser(aBrowser || gBrowser, this._ensureValid(aValue));
       else if (typeof this.globalValue != "undefined")
-        ZoomManager.zoom = this.globalValue;
+        ZoomManager.setZoomForBrowser(aBrowser || gBrowser, this.globalValue);
       else
-        ZoomManager.zoom = 1;
+        ZoomManager.setZoomForBrowser(aBrowser || gBrowser, 1);
     }
     catch(ex) {}
   },
 
   _applySettingToPref: function FullZoom__applySettingToPref() {
     if (!this.siteSpecific || gInPrintPreviewMode ||
         content.document instanceof Ci.nsIImageDocument)
       return;
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1953,17 +1953,17 @@ function readFromClipboard()
 {
   var url;
 
   try {
     // Get clipboard.
     var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
                               .getService(Components.interfaces.nsIClipboard);
 
-    // Create tranferable that will transfer the text.
+    // Create transferable that will transfer the text.
     var trans = Components.classes["@mozilla.org/widget/transferable;1"]
                           .createInstance(Components.interfaces.nsITransferable);
 
     trans.addDataFlavor("text/unicode");
 
     // If available, use selection clipboard, otherwise global one
     if (clipboard.supportsSelectionClipboard())
       clipboard.getData(trans, clipboard.kSelectionClipboard);
@@ -4030,18 +4030,16 @@ var XULBrowserWindow = {
         try {
           uri = this._uriFixup.createExposableURI(uri);
         } catch (e) {}
         URLBarSetURI(uri, true);
 
         // Update starring UI
         PlacesStarButton.updateState();
       }
-
-      FullZoom.onLocationChange(aLocationURI);
     }
     UpdateBackForwardCommands(gBrowser.webNavigation);
 
     if (gFindBar.findMode != gFindBar.FIND_NORMAL) {
       // Close the Find toolbar if we're in old-style TAF mode
       gFindBar.close();
     }
 
@@ -4167,16 +4165,17 @@ var XULBrowserWindow = {
       // e.g. about:blank. The _state for these pages means we won't need these
       // properties anyways, though.
     }
     gIdentityHandler.checkIdentity(this._state, locationObj);
   },
 
   // simulate all change notifications after switching tabs
   onUpdateCurrentBrowser: function (aStateFlags, aStatus, aMessage, aTotalProgress) {
+    FullZoom.onLocationChange(gBrowser.currentURI);
     var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
     var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
     // use a pseudo-object instead of a (potentially non-existing) channel for getting
     // a correct error message - and make sure that the UI is always either in
     // loading (STATE_START) or done (STATE_STOP) mode
     this.onStateChange(
       gBrowser.webProgress,
       { URI: gBrowser.currentURI },
@@ -4231,16 +4230,19 @@ var TabsProgressListener = {
                               aCurSelfProgress, aMaxSelfProgress,
                               aCurTotalProgress, aMaxTotalProgress) {
   },
 
   onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
   },
 
   onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
+    // Filter out any sub-frame loads
+    if (aBrowser.contentWindow == aWebProgress.DOMWindow)
+      FullZoom.onLocationChange(aLocationURI, aBrowser);
   },
   
   onStatusChange: function (aBrowser, aWebProgress, aRequest, aStatus, aMessage) {
   },
 
   onRefreshAttempted: function (aBrowser, aWebProgress, aURI, aDelay, aSameURI) {
     if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
       let brandBundle = document.getElementById("bundle_brand");
@@ -4389,63 +4391,24 @@ nsBrowserAccess.prototype =
           if(!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
             content.focus();
         } catch(e) {
         }
     }
     return newWindow;
   },
 
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-#define BROKEN_WM_Z_ORDER
-#endif
-#endif
-#ifdef XP_OS2
-#define BROKEN_WM_Z_ORDER
-#endif
-
   // this returns the most recent non-popup browser window
   _getMostRecentBrowserWindow : function ()
   {
     if (!window.document.documentElement.getAttribute("chromehidden"))
       return window;
  
-    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                       .getService(Components.interfaces.nsIWindowMediator);
- 
-#ifdef BROKEN_WM_Z_ORDER
-    var win = wm.getMostRecentWindow("navigator:browser", true);
- 
-    // if we're lucky, this isn't a popup, and we can just return this
-    if (win && win.document.documentElement.getAttribute("chromehidden")) {
-      win = null;
-      var windowList = wm.getEnumerator("navigator:browser", true);
-      // this is oldest to newest, so this gets a bit ugly
-      while (windowList.hasMoreElements()) {
-        var nextWin = windowList.getNext();
-        if (!nextWin.document.documentElement.getAttribute("chromehidden"))
-          win = nextWin;
-      }
-    }
-#else
-    var windowList = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
-    if (!windowList.hasMoreElements())
-      return null;
- 
-    var win = windowList.getNext();
-    while (win.document.documentElement.getAttribute("chromehidden")) {
-      if (!windowList.hasMoreElements()) 
-        return null;
- 
-      win = windowList.getNext();
-    }
-#endif
-
-    return win;
+    var browserGlue = Cc[GLUE_CID].getService(Ci.nsIBrowserGlue);
+    return browserGlue.getMostRecentBrowserWindow();
   },
 
   isTabContentWindow : function(aWindow)
   {
     return gBrowser.browsers.some(function (browser) browser.contentWindow == aWindow);
   }
 }
 
@@ -4949,16 +4912,19 @@ function middleMousePaste(event)
  *
  * Do not add any new fuctionality here other than what is needed for
  * a standalone product.
  */
 
 var contentAreaDNDObserver = {
   onDrop: function (aEvent, aXferData, aDragSession)
     {
+      if (aEvent.getPreventDefault())
+        return;
+
       var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
 
       // valid urls don't contain spaces ' '; if we have a space it
       // isn't a valid url, or if it's a javascript: or data: url,
       // bail out
       if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
           /^\s*(javascript|data):/.test(url))
         return;
--- a/browser/base/content/credits.xhtml
+++ b/browser/base/content/credits.xhtml
@@ -16,16 +16,17 @@
 #
 # The Initial Developer of the Original Code is Ben Goodger.
 # Portions created by the Initial Developer are Copyright (C) 2004
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Ben Goodger <ben@mozilla.org>
 #   David Baron <dbaron@mozilla.org>
+#   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -40,16 +41,18 @@
                       "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
   [
     <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
     %brandDTD;
     <!ENTITY % creditsDTD SYSTEM "chrome://browser/locale/credits.dtd">
     %creditsDTD;
     <!ENTITY % licenseDTD SYSTEM "chrome://global/locale/license.dtd">
     %licenseDTD;
+    <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+    %globalDTD;
   ]
 >
 
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>&brandFullName; Credits</title>
 
@@ -201,20 +204,20 @@
     </script>
   </head>
   <body onload="init();" onunload="uninit();">
     <div id="titleBox">
       <img src="chrome://branding/content/aboutCredits.png" />
     </div>
 
     <div id="creditsBox">
-        <h2 class="title">&brandFullName;&trade;
+        <h2 class="title" dir="&locale.dir;">&brandFullName;&trade;
           <div class="motto">&brandMotto;</div>
         </h2>
-        <div class="links">
+        <div class="links" dir="&locale.dir;">
           &credit.thanks2; <a href="" link="about:credits" onclick="visitLink(event);">&credit.contributors2;</a>
         </div>
 
         <div class="creditsGroup">
           <ul>
             <li>Josh Aas</li>
             <li>Robert Accettura</li>
             <li>Ehsan Akhgari</li>
@@ -489,22 +492,24 @@
             <li>Christine Yen</li>
             <li>Kohei Yoshino</li>
             <li>Shigeru Yoshitake</li>
             <li>Boris Zbarsky</li>
             <li>Marco Zehe</li>
             <li>Matthew Zeier</li>
           </ul>
 
-          &credit.translation;
+          <div dir="&locale.dir;">
+            &credit.translation;
+          </div>
         </div>
 
         <!-- organizational supporters -->
         <div class="creditsGroup">
-          <h3>&credit.thanks;</h3>
+          <h3 dir="&locale.dir;">&credit.thanks;</h3>
           <ul>
             <li>Google</li>
             <li>Yahoo!</li>
             <li>IBM</li>
             <li>Sun Microsystems</li>
             <li>Red Hat</li>
             <li></li>
             <li>Oregon State University - Open Source Lab</li>
@@ -521,19 +526,19 @@
             <li>Nobox</li>
             <li>silverorange</li>
             <li>Glaxstar</li>
             <li></li>
             <li>MozillaZine Community</li>
           </ul>
         </div>
 
-        <p id="gecko" class="center">&credit.poweredByGeckoReg;</p>
+        <p id="gecko" class="center" dir="&locale.dir;">&credit.poweredByGeckoReg;</p>
 
-        <p class="footnote">
+        <p class="footnote" dir="&locale.dir;">
           &brandFullName;&trade; &license.part0; &copy;1998-2009 &license.part1;
           <a href="" link="about:credits" onclick="visitLink(event);">&license.contrib;</a>,
           &license.part2;
           <a href="" link="about:license" onclick="visitLink(event);">about:license</a>
           &license.part3;</p>
 
         <p class="footnote">
           Mozilla Firefox&reg; and the Firefox logo are registered trademarks of the
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -114,17 +114,17 @@
             <xul:menuitem id="context_undoCloseTab"
                           label="&undoCloseTab.label;"
                           accesskey="&undoCloseTab.accesskey;"
                           command="History:UndoCloseTab"
                           anonid="undoCloseTabMenuItem"/>
             <xul:menuseparator/>
             <xul:menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
                           oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
-                                     tabbrowser.removeTab(tabbrowser.mContextTab);"/>
+                                     tabbrowser.removeClickedTab(tabbrowser.mContextTab);"/>
           </xul:menupopup>
 
           <xul:tabs class="tabbrowser-tabs" flex="1"
                     anonid="tabcontainer"
                     setfocus="false"
                     onclick="this.parentNode.parentNode.parentNode.onTabClick(event);"
                     xbl:inherits="onnewtab"
                     ondblclick="this.parentNode.parentNode.parentNode.onTabBarDblClick(event);"
@@ -1010,17 +1010,17 @@
 
       <method name="onTabClick">
         <parameter name="event"/>
         <body>
           <![CDATA[
             if (event.button != 1 || event.target.localName != 'tab')
               return;
 
-            this.removeTab(event.target);
+            this.removeClickedTab(event.target);
             event.stopPropagation();
           ]]>
         </body>
       </method>
 
       <method name="onTitleChanged">
         <parameter name="evt"/>
         <body>
@@ -1492,16 +1492,25 @@
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             this._endRemoveTab(this._beginRemoveTab(aTab, true));
           ]]>
         </body>
       </method>
 
+      <method name="removeClickedTab">
+        <parameter name="aTab"/>
+        <body>
+          <![CDATA[
+            this._endRemoveTab(this._beginRemoveTab(aTab, true, false));
+          ]]>
+        </body>
+      </method>
+
       <!-- Returns everything that _endRemoveTab needs in an array. -->
       <method name="_beginRemoveTab">
         <parameter name="aTab"/>
         <parameter name="aFireBeforeUnload"/>
         <parameter name="aCloseWindowWithLastTab"/>
         <body>
           <![CDATA[
             if (aFireBeforeUnload) {
@@ -1615,35 +1624,17 @@
             // Remove the tab
             this.mTabContainer.removeChild(aTab);
             // Update our length
             --length;
             // invalidate cache, because mTabContainer is about to change
             this._browsers = null; 
             this.mPanelContainer.removeChild(browser.parentNode);
 
-            try {
-              // if we're at the right side (and not the logical end,
-              // which is why this works for both LTR and RTL)
-              // of the tabstrip, we need to ensure that we stay 
-              // completely scrolled to the right side
-              var tabStrip = this.mTabContainer.mTabstrip;
-              var scrollPos = {};
-              tabStrip.scrollBoxObject.getPosition(scrollPos, {});
-              var scrolledSize = {};
-              tabStrip.scrollBoxObject.getScrolledSize(scrolledSize, {});
-
-              if (scrollPos.value + tabStrip.boxObject.width >= 
-                  scrolledSize.value) {
-                tabStrip.scrollByPixels(-1 * this.mTabContainer.firstChild
-                                                 .boxObject.width);
-              }
-            }
-            catch (ex) {
-            }
+            this.tabContainer._fillTrailingGap();
 
             // Find the tab to select
             var newIndex = -1;
             if (currentIndex > index)
               newIndex = currentIndex-1;
             else if (currentIndex < index)
               newIndex = currentIndex;
             else {
@@ -3106,41 +3097,61 @@
             this._mPrefs =
               Components.classes['@mozilla.org/preferences-service;1'].
               getService(Components.interfaces.nsIPrefBranch2);
           }
           return this._mPrefs;
         ]]>
         </getter>
       </property>
-        
+
       <method name="_handleTabSelect">
         <body><![CDATA[
           this.mTabstrip.ensureElementIsVisible(this.selectedItem);
         ]]></body>
       </method>
 
+      <method name="_fillTrailingGap">
+        <body><![CDATA[
+          try {
+            // if we're at the right side (and not the logical end,
+            // which is why this works for both LTR and RTL)
+            // of the tabstrip, we need to ensure that we stay
+            // completely scrolled to the right side
+            var tabStrip = this.mTabstrip;
+            var scrollPos = {};
+            tabStrip.scrollBoxObject.getPosition(scrollPos, {});
+            var scrolledSize = {};
+            tabStrip.scrollBoxObject.getScrolledSize(scrolledSize, {});
+
+            if (scrollPos.value + tabStrip.boxObject.width >=
+                scrolledSize.value) {
+              tabStrip.scrollByPixels(-1);
+            }
+          } catch (e) {}
+        ]]></body>
+      </method>
+
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
             case "overflow":
               this.setAttribute("overflow", "true");
               this.mTabstrip.scrollBoxObject
                             .ensureElementIsVisible(this.selectedItem);
               break;
             case "underflow":
               this.removeAttribute("overflow");
               break;
             case "resize":
               var width = this.mTabstrip.boxObject.width;
               if (width != this.mTabstripWidth) {
                 this.adjustTabstrip();
-                // XXX without this line the tab bar won't budge
-                this.mTabstrip.scrollByPixels(1);
+                this._fillTrailingGap();
                 this._handleTabSelect();
                 this.mTabstripWidth = width;
               }
               break;
           }
         ]]></body>
       </method>
 
@@ -3285,17 +3296,17 @@
             if (event.detail > 1 && !this._ignoredClick) {
               this._ignoredClick = true;
               return;
             }
 
             // Reset the "ignored click" flag
             this._ignoredClick = false;
 
-            tabbedBrowser.removeTab(bindingParent);
+            tabbedBrowser.removeClickedTab(bindingParent);
             tabbedBrowser._blockDblClick = true;
 
             /* XXXmano hack (see bug 343628):
              * Since we're removing the event target, if the user
              * double-clicks this button, the dblclick event will be dispatched
              * with the tabbar as its event target (and explicit/originalTarget),
              * which treats that as a mouse gesture for opening a new tab.
              * In this context, we're manually blocking the dblclick event
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -78,16 +78,18 @@ include $(topsrcdir)/config/rules.mk
                  plugin_unknown.html \
                  plugin_test.html \
                  plugin_both.html \
                  plugin_both2.html \
                  browser_alltabslistener.js \
                  alltabslistener.html \
                  zoom_test.html \
                  browser_bug416661.js \
+                 browser_bug386835.js \
+                 bug386835.html \
     $(NULL)
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 _BROWSER_FILES += browser_customize.js \
     $(NULL)
 endif
 
 libs:: $(_TEST_FILES)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug386835.js
@@ -0,0 +1,66 @@
+var gTestPage = "http://example.org/browser/browser/base/content/test/bug386835.html";
+var gTab1, gTab2, gTab3;
+var gLevel;
+
+function test() {
+  waitForExplicitFinish();
+
+  gTab1 = gBrowser.addTab(gTestPage);
+  gTab2 = gBrowser.addTab();
+  gTab3 = gBrowser.addTab();
+  gBrowser.selectedTab = gTab1;
+
+  gBrowser.getBrowserForTab(gTab1).addEventListener("load", tab1Loaded, true);
+}
+
+function tab1Loaded() {
+  gBrowser.getBrowserForTab(gTab1).removeEventListener("load", tab1Loaded, true);
+
+  gBrowser.getBrowserForTab(gTab2).addEventListener("load", tab2Loaded, true);
+  gBrowser.getBrowserForTab(gTab2).loadURI(gTestPage);
+}
+
+function tab2Loaded() {
+  gBrowser.getBrowserForTab(gTab2).removeEventListener("load", tab2Loaded, true);
+
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1)), 1, "Initial zoom of tab 1 should be 1");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab2)), 1, "Initial zoom of tab 2 should be 1");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab3)), 1, "Initial zoom of tab 3 should be 1");
+
+  // Now have three tabs, two with the test page, one blank. Tab 1 is selected
+  // Zoom tab 1
+  FullZoom.enlarge();
+  gLevel = ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1));
+
+  ok(gLevel != 1, "New zoom for tab 1 should not be 1");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab2)), 1, "Zooming tab 1 should not affect tab 2");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab3)), 1, "Zooming tab 1 should not affect tab 3");
+
+  gBrowser.getBrowserForTab(gTab3).addEventListener("load", tab3Loaded, true);
+  gBrowser.getBrowserForTab(gTab3).loadURI(gTestPage);
+}
+
+function tab3Loaded() {
+  gBrowser.getBrowserForTab(gTab3).removeEventListener("load", tab3Loaded, true);
+
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1)), gLevel, "Tab 1 should still be zoomed");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab2)), 1, "Tab 2 should still not be affected");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab3)), gLevel, "Tab 3 should have zoomed as it was loading in the background");
+
+  // Switching to tab 2 should update its zoom setting.
+  gBrowser.selectedTab = gTab2;
+
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab1)), gLevel, "Tab 1 should still be zoomed");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab2)), gLevel, "Tab 2 should be zoomed now");
+  is(ZoomManager.getZoomForBrowser(gBrowser.getBrowserForTab(gTab3)), gLevel, "Tab 3 should still be zoomed");
+
+  finishTest();
+}
+
+function finishTest() {
+  FullZoom.reset();
+  gBrowser.removeTab(gTab1);
+  gBrowser.removeTab(gTab2);
+  gBrowser.removeTab(gTab3);
+  finish();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/bug386835.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>Test page for bug 386835</title>
+</head>
+<body>
+<p>Test page for bug 386835</p>
+</body>
+</html>
--- a/browser/components/feeds/src/FeedWriter.js
+++ b/browser/components/feeds/src/FeedWriter.js
@@ -1260,17 +1260,17 @@ FeedWriter.prototype = {
     var defaultHandler = "reader";
     var useAsDefault = this._document.getElementById("alwaysUse")
                                      .getAttribute("checked");
 
     var handlersMenuList = this._document.getElementById("handlersMenuList");
     var selectedItem = this._getSelectedItemFromMenulist(handlersMenuList);
 
     // Show the file picker before subscribing if the
-    // choose application menuitem was choosen using the keyboard
+    // choose application menuitem was chosen using the keyboard
     if (selectedItem.id == "chooseApplicationMenuItem") {
       if (!this._chooseClientApp())
         return;
       
       selectedItem = this._getSelectedItemFromMenulist(handlersMenuList);
     }
 
     if (selectedItem.hasAttribute("webhandlerurl")) {
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -252,58 +252,21 @@ function openPreferences() {
 }
 
 function getMostRecentWindow(aType) {
   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                      .getService(nsIWindowMediator);
   return wm.getMostRecentWindow(aType);
 }
 
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-#define BROKEN_WM_Z_ORDER
-#endif
-#endif
-#ifdef XP_OS2
-#define BROKEN_WM_Z_ORDER
-#endif
-
 // this returns the most recent non-popup browser window
 function getMostRecentBrowserWindow() {
-  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                     .getService(Components.interfaces.nsIWindowMediator);
-
-#ifdef BROKEN_WM_Z_ORDER
-  var win = wm.getMostRecentWindow("navigator:browser", true);
-
-  // if we're lucky, this isn't a popup, and we can just return this
-  if (win && win.document.documentElement.getAttribute("chromehidden")) {
-    var windowList = wm.getEnumerator("navigator:browser", true);
-    // this is oldest to newest, so this gets a bit ugly
-    while (windowList.hasMoreElements()) {
-      var nextWin = windowList.getNext();
-      if (!nextWin.document.documentElement.getAttribute("chromehidden"))
-        win = nextWin;
-    }
-  }
-#else
-  var windowList = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
-  if (!windowList.hasMoreElements())
-    return null;
-
-  var win = windowList.getNext();
-  while (win.document.documentElement.getAttribute("chromehidden")) {
-    if (!windowList.hasMoreElements()) 
-      return null;
-
-    win = windowList.getNext();
-  }
-#endif
-
-  return win;
+  var browserGlue = Components.classes["@mozilla.org/browser/browserglue;1"]
+                              .getService(Components.interfaces.nsIBrowserGlue);
+  return browserGlue.getMostRecentBrowserWindow();
 }
 
 function doSearch(searchTerm, cmdLine) {
   var ss = Components.classes["@mozilla.org/browser/search-service;1"]
                      .getService(nsIBrowserSearchService);
 
   var submission = ss.defaultEngine.getSubmission(searchTerm, null);
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -561,17 +561,28 @@ BrowserGlue.prototype = {
 
     if (!importBookmarks) {
       // Call it here for Fx3 profiles created before the Places folder
       // has been added, otherwise it's called during import.
       this.ensurePlacesDefaultQueriesInitialized();
     }
     else {
       // ensurePlacesDefaultQueriesInitialized() is called by import.
-      this._prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
+      // Don't try to recreate smart bookmarks if autoExportHTML is true or
+      // smart bookmarks are disabled.
+      var autoExportHTML = false;
+      try {
+        autoExportHTML = this._prefs.getBoolPref("browser.bookmarks.autoExportHTML");
+      } catch(ex) {}
+      var smartBookmarksVersion = 0;
+      try {
+        smartBookmarksVersion = this._prefs.getIntPref("browser.places.smartBookmarksVersion");
+      } catch(ex) {}
+      if (!autoExportHTML && smartBookmarksVersion != -1)
+        this._prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
 
       // Get bookmarks.html file location
       var dirService = Cc["@mozilla.org/file/directory_service;1"].
                        getService(Ci.nsIProperties);
 
       var bookmarksFile = null;
       if (restoreDefaultBookmarks) {
         // User wants to restore bookmarks.html file from default profile folder
@@ -911,22 +922,17 @@ BrowserGlue.prototype = {
       Components.utils.reportError(ex);
     }
     finally {
       this._prefs.setIntPref(SMART_BOOKMARKS_PREF, SMART_BOOKMARKS_VERSION);
       this._prefs.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
     }
   },
 
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-#define BROKEN_WM_Z_ORDER
-#endif
-#endif
-#ifdef XP_OS2
+#ifndef XP_WIN
 #define BROKEN_WM_Z_ORDER
 #endif
 
   // this returns the most recent non-popup browser window
   getMostRecentBrowserWindow : function ()
   {
     var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
              getService(Components.interfaces.nsIWindowMediator);
--- a/browser/components/nsIBrowserGlue.idl
+++ b/browser/components/nsIBrowserGlue.idl
@@ -52,17 +52,17 @@ interface nsIDOMWindow;
  * elegant or stable in the mozilla codebase, but its aim is rather pragmatic:
  * 1) reducing the performance overhead which affects browser window load;
  * 2) allow global hooks (e.g. startup and shutdown observers) which survive
  * browser windows to accomplish browser-related activities, such as shutdown
  * sanitization (see bug #284086)
  *
  */ 
 
-[scriptable, uuid(01639c88-c0eb-4d75-9ee1-f325c1e04215)]
+[scriptable, uuid(781df699-17dc-4237-b3d7-876ddb7085e3)]
 interface nsIBrowserGlue : nsISupports
 {
   /** 
    * Deletes privacy sensitive data according to user preferences
    *
    * @param aParentWindow an optionally null window which is the parent of the 
    *        sanitization dialog
    *
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -367,23 +367,21 @@ var BookmarkPropertiesPanel = {
           }
 
           window.resizeTo(window.outerWidth, newHeight);
         }
       }
     };
 
     if (!this._element("tagsRow").collapsed) {
-      this._element("tagsSelector")
+      this._element("tagsSelectorRow")
           .addEventListener("DOMAttrModified", this._resizeListener, false);
     }
     if (!this._element("folderRow").collapsed) {
-      this._element("folderTree")
-          .addEventListener("DOMAttrModified", this._resizeListener, false);
-      this._element("newFolderBox")
+      this._element("folderTreeRow")
           .addEventListener("DOMAttrModified", this._resizeListener, false);
     }
 
     // Listen on uri fields to enable accept button if input is valid
     this._inputListener = {
       _self: this,
       handleEvent: function(event) {
         document.documentElement.getButton("accept").disabled =
@@ -459,31 +457,31 @@ var BookmarkPropertiesPanel = {
   _element: function BPP__element(aID) {
     return document.getElementById("editBMPanel_" + aID);
   },
 
   onDialogUnload: function BPP_onDialogUnload() {
     // gEditItemOverlay does not exist anymore here, so don't rely on it.
     // Calling removeEventListener with arguments which do not identify any
     // currently registered EventListener on the EventTarget has no effect.
-    this._element("tagsSelector")
+    this._element("tagsSelectorRow")
         .removeEventListener("DOMAttrModified", this._resizeListener, false);
-    this._element("folderTree")
-        .removeEventListener("DOMAttrModified", this._resizeListener, false);
-    this._element("newFolderBox")
+    this._element("folderTreeRow")
         .removeEventListener("DOMAttrModified", this._resizeListener, false);
     this._element("locationField")
         .removeEventListener("input", this._inputListener, false);
     this._element("feedLocationField")
         .removeEventListener("input", this._inputListener, false);
     this._element("siteLocationField")
         .removeEventListener("input", this._inputListener, false);
   },
 
   onDialogAccept: function BPP_onDialogAccept() {
+    // We must blur current focused element to save its changes correctly
+    document.commandDispatcher.focusedElement.blur();
     // The order here is important! We have to uninit the panel first, otherwise
     // late changes could force it to commit more transactions.
     gEditItemOverlay.uninitPanel(true);
     gEditItemOverlay = null;
     this._endBatch();
     window.arguments[0].performed = true;
   },
 
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -48,16 +48,17 @@ var gEditItemOverlay = {
   _allTags: [],
   _multiEdit: false,
   _itemType: -1,
   _readOnly: false,
   _microsummaries: null,
   _hiddenRows: [],
   _observersAdded: false,
   _staticFoldersListBuilt: false,
+  _initialized: false,
 
   get itemId() {
     return this._itemId;
   },
 
   get multiEdit() {
     return this._multiEdit;
   },
@@ -83,17 +84,17 @@ var gEditItemOverlay = {
       isQuery = this._uri.schemeIs("place");
 
     this._element("nameRow").collapsed = this._hiddenRows.indexOf("name") != -1;
     this._element("folderRow").collapsed =
       this._hiddenRows.indexOf("folderPicker") != -1 || this._readOnly;
     this._element("tagsRow").collapsed = !this._uri ||
       this._hiddenRows.indexOf("tags") != -1 || isQuery;
     // Collapse the tag selector if the item does not accept tags.
-    if (!this._element("tagsSelector").collapsed &&
+    if (!this._element("tagsSelectorRow").collapsed &&
         this._element("tagsRow").collapsed)
       this.toggleTagsSelector();
     this._element("descriptionRow").collapsed =
       this._hiddenRows.indexOf("description") != -1 || this._readOnly;
     this._element("keywordRow").collapsed = !isBookmark || this._readOnly ||
       this._hiddenRows.indexOf("keyword") != -1 || isQuery;
     this._element("locationRow").collapsed = !(this._uri && !isQuery) ||
       this._hiddenRows.indexOf("location") != -1;
@@ -118,16 +119,21 @@ var gEditItemOverlay = {
    *        * hiddenRows (Strings array): list of rows to be hidden regardless
    *          of the item edited. Possible values: "title", "location",
    *          "description", "keyword", "loadInSidebar", "feedLocation",
    *          "siteLocation", folderPicker"
    *        * forceReadOnly - set this flag to initialize the panel to its
    *          read-only (view) mode even if the given item is editable.
    */
   initPanel: function EIO_initPanel(aFor, aInfo) {
+    // For sanity ensure that the implementer has uninited the panel before
+    // trying to init it again, or we could end up leaking due to observers.
+    if (this._initialized)
+      this.uninitPanel(false);
+
     var aItemIdList;
     if (aFor.length) {
       aItemIdList = aFor;
       aFor = aItemIdList[0];
     }
     else if (this._multiEdit) {
       this._multiEdit = false;
       this._tags = [];
@@ -213,16 +219,17 @@ var gEditItemOverlay = {
         this._initTextField("tagsField", this._allTags.join(", "), false);
         this._element("itemsCountText").value =
           PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
                                            [this._itemIds.length]);
       }
 
       // tags selector
       this._rebuildTagsSelectorList();
+      this._initialized = true;
     }
 
     // name picker
     this._initNamePicker();
     
     this._showHideRows();
 
     // observe changes
@@ -509,22 +516,23 @@ var gEditItemOverlay = {
 
     // Make sure the drop-marker is shown
     namePicker.setAttribute("droppable", "true");
   },
 
   uninitPanel: function EIO_uninitPanel(aHideCollapsibleElements) {
     if (aHideCollapsibleElements) {
       // hide the folder tree if it was previously visible
-      if (!this._folderTree.collapsed)
+      var folderTreeRow = this._element("folderTreeRow");
+      if (!folderTreeRow.collapsed)
         this.toggleFolderTreeVisibility();
 
       // hide the tag selector if it was previously visible
-      var tagsSelector = this._element("tagsSelector");
-      if (!tagsSelector.collapsed)
+      var tagsSelectorRow = this._element("tagsSelectorRow");
+      if (!tagsSelectorRow.collapsed)
         this.toggleTagsSelector();
     }
 
     if (this._observersAdded) {
       if (this._itemId != -1)
         PlacesUtils.bookmarks.removeObserver(this);
 
       this._observersAdded = false;
@@ -535,16 +543,17 @@ var gEditItemOverlay = {
     }
     this._itemId = -1;
     this._uri = null;
     this._uris = [];
     this._tags = [];
     this._allTags = [];
     this._itemIds = [];
     this._multiEdit = false;
+    this._initialized = false;
   },
 
   onTagsFieldBlur: function EIO_onTagsFieldBlur() {
     this._updateTags();
   },
 
   _updateTags: function EIO__updateTags() {
     if (this._multiEdit)
@@ -743,31 +752,30 @@ var gEditItemOverlay = {
     var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
     var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId,
                                                  loadInSidebarChecked);
     PlacesUIUtils.ptm.doTransaction(txn);
   },
 
   toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() {
     var expander = this._element("foldersExpander");
-    if (!this._folderTree.collapsed) {
+    var folderTreeRow = this._element("folderTreeRow");
+    if (!folderTreeRow.collapsed) {
       expander.className = "expander-down";
       expander.setAttribute("tooltiptext",
                             expander.getAttribute("tooltiptextdown"));
-      this._folderTree.collapsed =
-        this._element("newFolderBox").collapsed = true;
+      folderTreeRow.collapsed = true;
       this._element("chooseFolderSeparator").hidden =
         this._element("chooseFolderMenuItem").hidden = false;
     }
     else {
       expander.className = "expander-up"
       expander.setAttribute("tooltiptext",
                             expander.getAttribute("tooltiptextup"));
-      this._folderTree.collapsed =
-        this._element("newFolderBox").collapsed = false;
+      folderTreeRow.collapsed = false;
 
       // XXXmano: Ideally we would only do this once, but for some odd reason,
       // the editable mode set on this tree, together with its collapsed state
       // breaks the view.
       const FOLDER_TREE_PLACE_URI =
         "place:excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1&folder=" +
         window.top.PlacesUIUtils.allBookmarksFolderId;
       this._folderTree.place = FOLDER_TREE_PLACE_URI;
@@ -839,26 +847,32 @@ var gEditItemOverlay = {
       // static list
       if (container != PlacesUtils.unfiledBookmarksFolderId &&
           container != PlacesUtils.toolbarFolderId &&
           container != PlacesUtils.bookmarksMenuFolderId)
         this._markFolderAsRecentlyUsed(container);
     }
 
     // Update folder-tree selection
-    if (!this._folderTree.collapsed) {
+    var folderTreeRow = this._element("folderTreeRow");
+    if (!folderTreeRow.collapsed) {
       var selectedNode = this._folderTree.selectedNode;
       if (!selectedNode ||
           PlacesUtils.getConcreteItemId(selectedNode) != container)
         this._folderTree.selectItems([container]);
     }
   },
 
   onFolderTreeSelect: function EIO_onFolderTreeSelect() {
     var selectedNode = this._folderTree.selectedNode;
+
+    // Disable the "New Folder" button if we cannot create a new folder
+    this._element("newFolderButton")
+        .disabled = !this._folderTree.insertionPoint || !selectedNode;
+
     if (!selectedNode)
       return;
 
     var folderId = PlacesUtils.getConcreteItemId(selectedNode);
     if (this._getFolderIdFromMenuList() == folderId)
       return;
 
     var folderItem = this._getFolderMenuItem(folderId);
@@ -902,17 +916,18 @@ var gEditItemOverlay = {
                  value: aLastUsed ? new Date().getTime() : null,
                  expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
 
     return anno;
   },
 
   _rebuildTagsSelectorList: function EIO__rebuildTagsSelectorList() {
     var tagsSelector = this._element("tagsSelector");
-    if (tagsSelector.collapsed)
+    var tagsSelectorRow = this._element("tagsSelectorRow");
+    if (tagsSelectorRow.collapsed)
       return;
 
     while (tagsSelector.hasChildNodes())
       tagsSelector.removeChild(tagsSelector.lastChild);
 
     var tagsInField = this._getTagsArrayFromTagField();
     var allTags = PlacesUtils.tagging.allTags;
     for (var i = 0; i < allTags.length; i++) {
@@ -924,32 +939,33 @@ var gEditItemOverlay = {
         elt.setAttribute("checked", "true");
 
       tagsSelector.appendChild(elt);
     }
   },
 
   toggleTagsSelector: function EIO_toggleTagsSelector() {
     var tagsSelector = this._element("tagsSelector");
+    var tagsSelectorRow = this._element("tagsSelectorRow");
     var expander = this._element("tagsSelectorExpander");
-    if (tagsSelector.collapsed) {
+    if (tagsSelectorRow.collapsed) {
       expander.className = "expander-up";
       expander.setAttribute("tooltiptext",
                             expander.getAttribute("tooltiptextup"));
-      tagsSelector.collapsed = false;
+      tagsSelectorRow.collapsed = false;
       this._rebuildTagsSelectorList();
 
       // This is a no-op if we've added the listener.
       tagsSelector.addEventListener("CheckboxStateChange", this, false);
     }
     else {
       expander.className = "expander-down";
       expander.setAttribute("tooltiptext",
                             expander.getAttribute("tooltiptextdown"));
-      tagsSelector.collapsed = true;
+      tagsSelectorRow.collapsed = true;
     }
   },
 
   _getTagsArrayFromTagField: function EIO__getTagsArrayFromTagField() {
     // we don't require the leading space (after each comma)
     var tags = this._element("tagsField").value.split(",");
     for (var i=0; i < tags.length; i++) {
       // remove trailing and leading spaces
@@ -963,21 +979,20 @@ var gEditItemOverlay = {
     }
     return tags;
   },
 
   newFolder: function EIO_newFolder() {
     var ip = this._folderTree.insertionPoint;
 
     // default to the bookmarks menu folder
-    if (!ip ||
-        ip.itemId == PlacesUIUtils.allBookmarksFolderId ||
-        ip.itemId == PlacesUIUtils.unfiledBookmarksFolderId) {
-      ip.itemId = PlacesUtils.bookmarksMenuFolderId;
-      ip.index = -1;
+    if (!ip || ip.itemId == PlacesUIUtils.allBookmarksFolderId) {
+        ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
+                                PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                Ci.nsITreeView.DROP_ON);
     }
 
     // XXXmano: add a separate "New Folder" string at some point...
     var defaultLabel = this._element("newFolderButton").label;
     var txn = PlacesUIUtils.ptm.createFolder(defaultLabel, ip.itemId, ip.index);
     PlacesUIUtils.ptm.doTransaction(txn);
     this._folderTree.focus();
     this._folderTree.selectItems([this._lastNewItem]);
--- a/browser/components/places/content/editBookmarkOverlay.xul
+++ b/browser/components/places/content/editBookmarkOverlay.xul
@@ -44,16 +44,20 @@
 <?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
 
 <overlay id="editBookmarkOverlay"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <vbox id="editBookmarkPanelContent">
     <broadcaster id="paneElementsBroadcaster"/>
 
+    <hbox id="editBMPanel_selectionCount" hidden="true" pack="center">
+      <label id="editBMPanel_itemsCountText"/>
+    </hbox>
+
     <grid id="editBookmarkPanelGrid" flex="1">
       <columns>
         <column/>
         <column flex="1"/>
       </columns>
       <rows>
         <row align="center" id="editBMPanel_nameRow">
           <label value="&editBookmarkOverlay.name.label;"
@@ -107,104 +111,110 @@
                    onblur="gEditItemOverlay.onSiteLocationFieldBlur();"
                    observes="paneElementsBroadcaster"/>
         </row>
 
         <row align="center" id="editBMPanel_folderRow">
           <label value="&editBookmarkOverlay.folder.label;"
                  control="editBMPanel_folderMenuList"
                  observes="paneElementsBroadcaster"/>
-          <menulist id="editBMPanel_folderMenuList"
-                    class="folder-icon"
-                    oncommand="gEditItemOverlay.onFolderMenuListCommand(event);"
-                    observes="paneElementsBroadcaster">
-            <menupopup>
-              <!-- Static item for special folders -->
-              <menuitem id="editBMPanel_toolbarFolderItem"
-                        class="menuitem-iconic folder-icon"/>
-              <menuitem id="editBMPanel_bmRootItem"
-                        class="menuitem-iconic folder-icon"/>
-              <menuitem id="editBMPanel_unfiledRootItem"
-                        class="menuitem-iconic folder-icon"/>
-              <menuseparator id="editBMPanel_chooseFolderSeparator"/>
-              <menuitem id="editBMPanel_chooseFolderMenuItem"
-                        label="&editBookmarkOverlay.choose.label;"
-                        class="menuitem-iconic folder-icon"/>
-              <menuseparator id="editBMPanel_foldersSeparator" hidden="true"/>
-            </menupopup>
-          </menulist>
-          <button id="editBMPanel_foldersExpander"
-                  class="expander-down"
-                  tooltiptext="&editBookmarkOverlay.foldersExpanderDown.tooltip;"
-                  tooltiptextdown="&editBookmarkOverlay.foldersExpanderDown.tooltip;"
-                  tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
-                  oncommand="gEditItemOverlay.toggleFolderTreeVisibility();"
-                  observes="paneElementsBroadcaster"/>
+          <hbox flex="1" align="center">
+            <menulist id="editBMPanel_folderMenuList"
+                      class="folder-icon"
+                      flex="1"
+                      oncommand="gEditItemOverlay.onFolderMenuListCommand(event);"
+                      observes="paneElementsBroadcaster">
+              <menupopup>
+                <!-- Static item for special folders -->
+                <menuitem id="editBMPanel_toolbarFolderItem"
+                          class="menuitem-iconic folder-icon"/>
+                <menuitem id="editBMPanel_bmRootItem"
+                          class="menuitem-iconic folder-icon"/>
+                <menuitem id="editBMPanel_unfiledRootItem"
+                          class="menuitem-iconic folder-icon"/>
+                <menuseparator id="editBMPanel_chooseFolderSeparator"/>
+                <menuitem id="editBMPanel_chooseFolderMenuItem"
+                          label="&editBookmarkOverlay.choose.label;"
+                          class="menuitem-iconic folder-icon"/>
+                <menuseparator id="editBMPanel_foldersSeparator" hidden="true"/>
+              </menupopup>
+            </menulist>
+            <button id="editBMPanel_foldersExpander"
+                    class="expander-down"
+                    tooltiptext="&editBookmarkOverlay.foldersExpanderDown.tooltip;"
+                    tooltiptextdown="&editBookmarkOverlay.foldersExpanderDown.tooltip;"
+                    tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
+                    oncommand="gEditItemOverlay.toggleFolderTreeVisibility();"
+                    observes="paneElementsBroadcaster"/>
+          </hbox>
         </row>
 
-        <tree id="editBMPanel_folderTree"
-              class="placesTree"
-              type="places"
-              height="150"
-              collapsed="true"
-              editable="true"
-              onselect="gEditItemOverlay.onFolderTreeSelect();"
-              hidecolumnpicker="true"
-              observes="paneElementsBroadcaster">
-          <treecols>
-            <treecol anonid="title" flex="1" primary="true" hideheader="true"/>
-          </treecols>
-          <treechildren flex="1"/>
-        </tree>
+        <row align="center" id="editBMPanel_folderTreeRow" collapsed="true">
+          <spacer/>
+          <vbox flex="1">
+            <tree id="editBMPanel_folderTree"
+                  class="placesTree"
+                  type="places"
+                  height="150"
+                  editable="true"
+                  onselect="gEditItemOverlay.onFolderTreeSelect();"
+                  hidecolumnpicker="true"
+                  observes="paneElementsBroadcaster">
+              <treecols>
+                <treecol anonid="title" flex="1" primary="true" hideheader="true"/>
+              </treecols>
+              <treechildren flex="1"/>
+            </tree>
 
-        <hbox id="editBMPanel_newFolderBox" collapsed="true">
-          <button label="&editBookmarkOverlay.newFolderButton.label;"
-                  id="editBMPanel_newFolderButton"
-                  accesskey="&editBookmarkOverlay.newFolderButton.accesskey;"
-                  oncommand="gEditItemOverlay.newFolder();"/>
-          <spacer flex="1"/>
-        </hbox>
-
-        <row align="center" id="editBMPanel_selectionCount" hidden="true">
-          <spacer flex="3"/>
-          <vbox id="editBMPanel_itemsCountBox" align="center">
-            <label id="editBMPanel_itemsCountText"/>
+            <hbox id="editBMPanel_newFolderBox">
+              <button label="&editBookmarkOverlay.newFolderButton.label;"
+                      id="editBMPanel_newFolderButton"
+                      accesskey="&editBookmarkOverlay.newFolderButton.accesskey;"
+                      oncommand="gEditItemOverlay.newFolder();"/>
+            </hbox>
           </vbox>
-          <spacer flex="3"/>
         </row>
 
         <row align="center" id="editBMPanel_tagsRow">
           <label value="&editBookmarkOverlay.tags.label;"
                  accesskey="&editBookmarkOverlay.tags.accesskey;"
                  control="editBMPanel_tagsField"
                  observes="paneElementsBroadcaster"/>
-          <textbox id="editBMPanel_tagsField"
-                   type="autocomplete"
-                   class="padded"
-                   autocompletesearch="places-tag-autocomplete" 
-                   completedefaultindex="true"
-                   tabscrolling="true"
-                   showcommentcolumn="true"
-                   onblur="gEditItemOverlay.onTagsFieldBlur();"
-                   observes="paneElementsBroadcaster"
-                   emptytext="&editBookmarkOverlay.tagsEmptyDesc.label;"/>
-          <button id="editBMPanel_tagsSelectorExpander"
-                  class="expander-down"
-                  tooltiptext="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
-                  tooltiptextdown="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
-                  tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
-                  oncommand="gEditItemOverlay.toggleTagsSelector();"
-                  observes="paneElementsBroadcaster"/>
+          <hbox flex="1" align="center">
+            <textbox id="editBMPanel_tagsField"
+                     type="autocomplete"
+                     class="padded"
+                     flex="1"
+                     autocompletesearch="places-tag-autocomplete" 
+                     completedefaultindex="true"
+                     tabscrolling="true"
+                     showcommentcolumn="true"
+                     onblur="gEditItemOverlay.onTagsFieldBlur();"
+                     observes="paneElementsBroadcaster"
+                     emptytext="&editBookmarkOverlay.tagsEmptyDesc.label;"/>
+            <button id="editBMPanel_tagsSelectorExpander"
+                    class="expander-down"
+                    tooltiptext="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
+                    tooltiptextdown="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
+                    tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
+                    oncommand="gEditItemOverlay.toggleTagsSelector();"
+                    observes="paneElementsBroadcaster"/>
+          </hbox>
         </row>
 
-        <listbox id="editBMPanel_tagsSelector"
-                 height="150" collapsed="true"
-                 observes="paneElementsBroadcaster"/>
+        <row id="editBMPanel_tagsSelectorRow"
+             align="center"
+             collapsed="true">
+          <spacer/>
+          <listbox id="editBMPanel_tagsSelector"
+                   height="150"
+                   observes="paneElementsBroadcaster"/>
+        </row>
 
-        <row id="editBMPanel_keywordRow">
+        <row align="center" id="editBMPanel_keywordRow">
           <label value="&editBookmarkOverlay.keyword.label;"
                  accesskey="&editBookmarkOverlay.keyword.accesskey;"
                  control="editBMPanel_keywordField"
                  observes="paneElementsBroadcaster"/>
           <textbox id="editBMPanel_keywordField"
                    onblur="gEditItemOverlay.onKeywordFieldBlur();"
                    observes="paneElementsBroadcaster"/>
         </row>
@@ -214,17 +224,19 @@
                  accesskey="&editBookmarkOverlay.description.accesskey;"
                  control="editBMPanel_descriptionField"
                  observes="paneElementsBroadcaster"/>
           <textbox id="editBMPanel_descriptionField"
                    multiline="true"
                    onblur="gEditItemOverlay.onDescriptionFieldBlur();"
                    observes="paneElementsBroadcaster"/>
         </row>
-        <checkbox id="editBMPanel_loadInSidebarCheckbox"
-                  label="&editBookmarkOverlay.loadInSidebar.label;"
-                  accesskey="&editBookmarkOverlay.loadInSidebar.accesskey;"
-                  oncommand="gEditItemOverlay.onLoadInSidebarCheckboxCommand();"
-                  observes="paneElementsBroadcaster"/>
       </rows>
     </grid>
+
+    <checkbox id="editBMPanel_loadInSidebarCheckbox"
+              label="&editBookmarkOverlay.loadInSidebar.label;"
+              accesskey="&editBookmarkOverlay.loadInSidebar.accesskey;"
+              oncommand="gEditItemOverlay.onLoadInSidebarCheckboxCommand();"
+              observes="paneElementsBroadcaster"/>
+
   </vbox>
 </overlay>
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -660,17 +660,20 @@ var PlacesOrganizer = {
         focusedElement.blur();
 
       // don't update the panel if we are already editing this node unless we're
       // in multi-edit mode
       if (aSelectedNode && gEditItemOverlay.itemId == aSelectedNode.itemId &&
           detailsDeck.selectedIndex == 1 && !gEditItemOverlay.multiEdit)
         return;
     }
- 
+
+    // Clean up the panel before initing it again.
+    gEditItemOverlay.uninitPanel(false);
+
     if (aSelectedNode && !PlacesUtils.nodeIsSeparator(aSelectedNode)) {
       detailsDeck.selectedIndex = 1;
       // Using the concrete itemId is arguably wrong. The bookmarks API
       // does allow setting properties for folder shortcuts as well, but since
       // the UI does not distinct between the couple, we better just show
       // the concrete item properties.
       if (aSelectedNode.type ==
           Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -36,16 +36,18 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK ***** 
 
 
 <!DOCTYPE bindings [
+<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
+%globalDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
 %browserDTD;
 ]>
 
 <bindings id="placesToolbarBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xbl="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
@@ -73,16 +75,17 @@
       <xul:hbox mousethrough="always"
                 flex="1"
                 pack="end">
         <xul:toolbarbutton type="menu"
                            class="chevron"
                            mousethrough="never"
                            collapsed="true"
                            tooltiptext="&bookmarksToolbarChevron.tooltip;"
+                           chromedir="&locale.dir;"
                            onpopupshowing="chevronPopupShowing(event);">
           <xul:menupopup anonid="chevronPopup"
                          xbl:inherits="tooltip"
 #ifndef XP_MACOSX
                          context="placesContext"
 #endif
           />
         </xul:toolbarbutton>
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -399,35 +399,27 @@ PlacesTreeView.prototype = {
                                previouslySelectedNodes[0].oldIndex, true);
       }
     }
     selection.selectEventsSuppressed = false;
   },
 
   _convertPRTimeToString: function PTV__convertPRTimeToString(aTime) {
     var timeInMilliseconds = aTime / 1000; // PRTime is in microseconds
-    var timeObj = new Date(timeInMilliseconds);
+
+    // Date is calculated starting from midnight, so the modulo with a day are
+    // milliseconds from today's midnight.
+    var now = Date.now();
+    var midnight = now - (now % (24 * 60 * 60 * 1000));
 
-    // Check if it is today and only display the time.  Only bother
-    // checking for today if it's within the last 24 hours, since
-    // computing midnight is not really cheap. Sometimes we may get dates
-    // in the future, so always show those.
-    var ago = new Date(Date.now() - timeInMilliseconds);
-    var dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
-    if (ago > -10000 && ago < (1000 * 24 * 60 * 60)) {
-      var midnight = new Date(timeInMilliseconds);
-      midnight.setHours(0);
-      midnight.setMinutes(0);
-      midnight.setSeconds(0);
-      midnight.setMilliseconds(0);
+    var dateFormat = timeInMilliseconds > midnight ?
+                      Ci.nsIScriptableDateFormat.dateFormatNone :
+                      Ci.nsIScriptableDateFormat.dateFormatShort;
 
-      if (timeInMilliseconds > midnight.getTime())
-        dateFormat = Ci.nsIScriptableDateFormat.dateFormatNone;
-    }
-
+    var timeObj = new Date(timeInMilliseconds);
     return (this._dateService.FormatDateTime("", dateFormat,
       Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
       timeObj.getFullYear(), timeObj.getMonth() + 1,
       timeObj.getDate(), timeObj.getHours(),
       timeObj.getMinutes(), timeObj.getSeconds()));
   },
 
   COLUMN_TYPE_UNKNOWN: 0,
--- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
+++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
@@ -53,30 +53,16 @@
   <head>
 #ifdef XP_MACOSX
     <title></title>
 #else
     <title>&privatebrowsingpage.title;</title>
 #endif
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all"/>
     <link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
-    <style type="text/css"><![CDATA[
-      body.normal .showPrivate {
-        display: none;
-      }
-      body.normal .showNormal {
-        display: block;
-      }
-      body.private .showPrivate {
-        display: block;
-      }
-      body.private .showNormal {
-        display: none;
-      }
-    ]]></style>
     <script type="application/x-javascript;version=1.7"><![CDATA[
       const Cc = Components.classes;
       const Ci = Components.interfaces;
 
       function openSanitizeDialog() {
         let mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIWebNavigation)
                                .QueryInterface(Ci.nsIDocShellTreeItem)
@@ -92,25 +78,34 @@
         var icon = document.createElement("link");
         icon.setAttribute("rel", "icon");
         icon.setAttribute("type", "image/png");
         icon.setAttribute("href", url);
         document.getElementsByTagName("head")[0].appendChild(icon);
       }
 
       function onLoad() {
+        let selector;
         let pb = Cc["@mozilla.org/privatebrowsing;1"].
                  getService(Ci.nsIPrivateBrowsingService);
         if (!pb.privateBrowsingEnabled) {
           document.body.setAttribute("class", "normal");
           document.title = document.body.getAttribute("normaltitle");
           setFavIcon("chrome://global/skin/icons/question-16.png");
+          selector = ".showPrivate";
         }
-        else
+        else {
           setFavIcon("chrome://browser/skin/Privacy-16.png");
+          selector = ".showNormal";
+        }
+
+        // Remove hidden elements to avoid bug 39098
+        let elements = document.body.querySelectorAll(selector);
+        for (let i = 0; i < elements.length; ++ i)
+          elements[i].parentNode.removeChild(elements[i]);
       }
     ]]></script>
   </head>
 
   <body dir="&locale.dir;"
         class="private"
         onload="onLoad();"
         normaltitle="&privatebrowsingpage.title.normal;">
--- a/browser/components/safebrowsing/content/application.js
+++ b/browser/components/safebrowsing/content/application.js
@@ -162,11 +162,10 @@ PROT_Application.prototype.getURIFlags =
 
 PROT_Application.prototype.QueryInterface = function(iid) {
   if (iid.equals(Ci.nsISupports) ||
       iid.equals(Ci.nsISupportsWeakReference) ||
       iid.equals(Ci.nsIObserver) ||
       iid.equals(Ci.nsIAboutModule))
     return this;
 
-  Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
-  return null;
+  throw Components.results.NS_ERROR_NO_INTERFACE;
 }
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -137,56 +137,49 @@ Window.prototype = {
       this._cleanup[aType] = function(e){ self._event(e); },
       true);
   },
 
   /*
    * Helper event callback used to redirect events made on the XBL element
    */
   _event : function win_event(aEvent) {
-    this._events.dispatch(aEvent.type, "");
+    this._events.dispatch(aEvent.type, new BrowserTab(this, aEvent.originalTarget.linkedBrowser));
   },
-
   get tabs() {
     var tabs = [];
     var browsers = this._tabbrowser.browsers;
-
     for (var i=0; i<browsers.length; i++)
-      tabs.push(new BrowserTab(this._window, browsers[i]));
-
+      tabs.push(new BrowserTab(this, browsers[i]));
     return tabs;
   },
-
   get activeTab() {
-    return new BrowserTab(this._window, this._tabbrowser.selectedBrowser);
+    return new BrowserTab(this, this._tabbrowser.selectedBrowser);
   },
-
   open : function win_open(aURI) {
-    return new BrowserTab(this._window, this._tabbrowser.addTab(aURI.spec).linkedBrowser);
+    return new BrowserTab(this, this._tabbrowser.addTab(aURI.spec).linkedBrowser);
   },
-
   _shutdown : function win_shutdown() {
     for (var type in this._cleanup)
       this._tabbrowser.removeEventListener(type, this._cleanup[type], true);
     this._cleanup = null;
 
     this._window = null;
     this._tabbrowser = null;
     this._events = null;
   },
 
   QueryInterface : XPCOMUtils.generateQI([Ci.fuelIWindow])
 };
 
-
 //=================================================
 // BrowserTab implementation
-function BrowserTab(aWindow, aBrowser) {
-  this._window = aWindow;
-  this._tabbrowser = aWindow.getBrowser();
+function BrowserTab(aFUELWindow, aBrowser) {
+  this._window = aFUELWindow;
+  this._tabbrowser = aFUELWindow._tabbrowser;
   this._browser = aBrowser;
   this._events = new Events();
   this._cleanup = {};
 
   this._watch("load");
 
   var self = this;
   gShutdown.push(function() { self._shutdown(); });
@@ -235,20 +228,18 @@ BrowserTab.prototype = {
     if (aEvent.type == "load") {
       if (!(aEvent.originalTarget instanceof Ci.nsIDOMDocument))
         return;
 
       if (aEvent.originalTarget.defaultView instanceof Ci.nsIDOMWindowInternal &&
           aEvent.originalTarget.defaultView.frameElement)
         return;
     }
-
-    this._events.dispatch(aEvent.type, "");
+    this._events.dispatch(aEvent.type, this);
   },
-
   /*
    * Helper used to determine the index offset of the browsertab
    */
   _getTab : function bt_gettab() {
     var tabs = this._tabbrowser.mTabs;
     return tabs[this.index] || null;
   },
 
--- a/browser/fuel/test/browser_ApplicationPrefs.js
+++ b/browser/fuel/test/browser_ApplicationPrefs.js
@@ -153,18 +153,25 @@ function test() {
   Application.prefs.events.addListener("change", onPrefChange);
   Application.prefs.setValue("fuel.fuel-test", "change event");
 }
 
 function onPrefChange(evt) {
   is(evt.data, testdata.dummy, "Check 'Application.prefs.set' fired a change event");
   Application.prefs.events.removeListener("change", onPrefChange);
 
+  // We are removing the old listener after adding the new listener so we can test that
+  // removing a listener does not remove all listeners
+  Application.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChangeDummy);
   Application.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2);
+  Application.prefs.get("fuel.fuel-test").events.removeListener("change", onPrefChangeDummy);
+
   Application.prefs.setValue("fuel.fuel-test", "change event2");
 }
 
 function onPrefChange2(evt) {
   is(evt.data, testdata.dummy, "Check 'Application.prefs.set' fired a change event for a single preference");
   Application.prefs.events.removeListener("change", onPrefChange2);
 
   finish();
 }
+
+function onPrefChangeDummy(evt) { }
--- a/browser/fuel/test/browser_Browser.js
+++ b/browser/fuel/test/browser_Browser.js
@@ -1,19 +1,21 @@
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 
 function url(spec) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
   return ios.newURI(spec, null, null);
 }
-
 var gPageA = null;
 var gPageB = null;
 
+// cached data from events
+var gTabOpenPageA = null;
+var gTabOpenPageB = null;
 var gTabOpenCount = 0;
 var gTabCloseCount = 0;
 var gTabMoveCount = 0;
 var gPageLoadCount = 0;
 
 function test() {
   var windows = Application.windows;
   ok(windows, "Check access to browser windows");
@@ -28,43 +30,52 @@ function test() {
   gPageA.events.addListener("load", onPageAFirstLoad);
 
   is(activeWin.tabs.length, 2, "Checking length of 'Browser.tabs' after opening 1 additional tab");
 
   waitForExplicitFinish();
 
   function onPageAFirstLoad(event) {
     gPageA.events.removeListener("load", onPageAFirstLoad);
+    is(gPageA.uri.spec, event.data.uri.spec, "Checking event browser tab is equal to page A");
 
     gPageB = activeWin.open(url("chrome://mochikit/content/browser/browser/fuel/test/ContentB.html"));
-    gPageB.events.addListener("load", function() {
-      executeSoon(afterOpen);
-    });
+    gPageB.events.addListener("load", delayAfterOpen);
     gPageB.focus();
 
     is(activeWin.tabs.length, 3, "Checking length of 'Browser.tabs' after opening a second additional tab");
     is(activeWin.activeTab.index, gPageB.index, "Checking 'Browser.activeTab' after setting focus");
   }
 
+  function delayAfterOpen() {
+    executeSoon(afterOpen);
+  }
+
   // need to wait for the url's to be refreshed during the load
   function afterOpen(event) {
-    gPageB.events.removeListener("load", afterOpen);
-
+    gPageB.events.removeListener("load", delayAfterOpen);
+    // check actuals
     is(gPageA.uri.spec, "chrome://mochikit/content/browser/browser/fuel/test/ContentA.html", "Checking 'BrowserTab.uri' after opening");
     is(gPageB.uri.spec, "chrome://mochikit/content/browser/browser/fuel/test/ContentB.html", "Checking 'BrowserTab.uri' after opening");
 
+    // check cached values from TabOpen event
+    is(gPageA.uri.spec, gTabOpenPageA.uri.spec, "Checking first browser tab open is equal to page A");
+    is(gPageB.uri.spec, gTabOpenPageB.uri.spec, "Checking second browser tab open is equal to page B");
     // check event
     is(gTabOpenCount, 2, "Checking event handler for tab open");
 
     // test document access
     var test1 = gPageA.document.getElementById("test1");
     ok(test1, "Checking existence of element in content DOM");
     is(test1.innerHTML, "A", "Checking content of element in content DOM");
 
     // test moving tab
+    is(gTabMoveCount, 0, "Checking initial tab move count");
+
+    // move the tab
     gPageA.moveToEnd();
     is(gPageA.index, 2, "Checking index after moving tab");
 
     // check event
     is(gTabMoveCount, 1, "Checking event handler for tab move");
 
     let browser = gBrowser.getBrowserAtIndex(gPageB.index);
     browser.addProgressListener({
@@ -73,43 +84,47 @@ function test() {
                          Ci.nsIWebProgressListener.STATE_IS_NETWORK +
                          Ci.nsIWebProgressListener.STATE_STOP;
         if ((stateFlags & complete) == complete) {
           browser.removeProgressListener(this);
           onPageBLoadComplete();
         }
       },
 
+      onLocationChange: function() { return 0; },
+      onProgressChange: function() { return 0; },
+      onStatusChange: function() { return 0; },
+      onSecurityChange: function() { return 0; },
       QueryInterface: function(iid) {
         if (iid.equals(Ci.nsISupportsWeakReference) ||
            iid.equals(Ci.nsIWebProgressListener) ||
            iid.equals(Ci.nsISupports))
            return this;
 
         throw Components.results.NS_ERROR_NO_INTERFACE;
       }
     });
 
     // test loading new content with a frame into a tab
-    // the event will be checked in afterClose
+    // the event will be checked in onPageBLoadComplete
     gPageB.events.addListener("load", onPageBLoadWithFrames);
     gPageB.load(url("chrome://mochikit/content/browser/browser/fuel/test/ContentWithFrames.html"));
   }
 
   function onPageBLoadWithFrames(event) {
     gPageLoadCount++;
   }
 
   function onPageBLoadComplete() {
     gPageB.events.removeListener("load", onPageBLoadWithFrames);
     // check page load with frame event
     is(gPageLoadCount, 1, "Checking load count after loading new content with a frame");
 
     // test loading new content into a tab
-    // the event will be checked in onPageLoad
+    // the event will be checked in onPageASecondLoad
     gPageA.events.addListener("load", onPageASecondLoad);
     gPageA.load(url("chrome://mochikit/content/browser/browser/fuel/test/ContentB.html"));
   }
 
   function onPageASecondLoad(event) {
     gPageA.events.removeListener("load", onPageASecondLoad);
     is(gPageA.uri.spec, "chrome://mochikit/content/browser/browser/fuel/test/ContentB.html", "Checking 'BrowserTab.uri' after loading new content");
 
@@ -120,20 +135,25 @@ function test() {
     gPageA.close();
     gPageB.close();
 
     is(gTabCloseCount, 2, "Checking that tabs closed");
     is(activeWin.tabs.length, 1, "Checking length of 'Browser.tabs' after closing 2 tabs");
     finish();
   }
 }
-
 function onTabOpen(event) {
   gTabOpenCount++;
+
+  // cache these values so we can check them later (after loading completes)
+  if (gTabOpenCount == 1)
+    gTabOpenPageA = event.data;
+
+  if (gTabOpenCount == 2)
+    gTabOpenPageB = event.data;
 }
-
 function onTabClose(event) {
   gTabCloseCount++;
 }
 
 function onTabMove(event) {
   gTabMoveCount++;
 }
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -64,19 +64,18 @@ ifeq (WINNT,$(OS_ARCH))
 MOZ_PKG_MANIFEST_P = $(srcdir)/windows/packages-static
 else
 ifneq (,$(filter-out OS2 Darwin,$(OS_ARCH)))
 MOZ_PKG_MANIFEST_P = $(srcdir)/unix/packages-static
 endif
 endif
 else
 define message
-Please don't package debug builds.
-Your build was configured without --enable-static or --enable-libxul.
-This is probably because it's a debug build
+You need to build with --enable-libxul (the default, unless you specify
+--disable-libxul or --enable-shared or --enable-debug) to package a build.
 endef
 default libs installer::
 	$(error $(message))
 endif
 
 MOZ_NONLOCALIZED_PKG_LIST = \
 	xpcom \
 	browser \
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -337,16 +337,19 @@ bin/res/charsetalias.properties
 bin/res/charsetData.properties
 bin/res/langGroups.properties
 bin/res/language.properties
 bin/res/entityTables/*
 
 ; svg
 bin/res/svg.css
 bin/components/dom_svg.xpt
+#ifdef MOZ_SMIL
+bin/components/dom_smil.xpt
+#endif
 
 ; [Personal Security Manager]
 ;
 bin/libnssckbi.so
 bin/components/pipboot.xpt
 bin/components/pipnss.xpt
 bin/components/pippki.xpt
 bin/libnss3.so
--- a/browser/installer/windows/Makefile.in
+++ b/browser/installer/windows/Makefile.in
@@ -16,16 +16,17 @@
 # The Initial Developer of the Original Code is
 # IBM Corporation.
 # Portions created by the Initial Developer are Copyright (C) 2004
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #  Brian Ryner <bryner@brianryner.com>
 #  Chase Phillips <cmp@mozilla.org>
+#  Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -47,78 +48,111 @@ include $(topsrcdir)/toolkit/mozapps/ins
 
 CONFIG_DIR = instgen
 SFX_MODULE = $(topsrcdir)/other-licenses/7zstub/firefox/7zSD.sfx
 
 PP_LOCALIZED_FILES = \
 	packages-static \
 	$(NULL)
 
-INSTALLER_FILES = \
-	app.tag \
+# All script and locale files used by the Unicode version of NSIS need to be
+# converted from UTF-8 to UTF-16LE
+INSTALLER_FILES_CONV = \
 	nsis/installer.nsi \
 	nsis/uninstaller.nsi \
 	nsis/shared.nsh \
 	$(NULL)
 
+INSTALLER_FILES = \
+	app.tag \
+	$(NULL)
+
+# All script and locale files used by the Unicode version of NSIS need to be
+# converted from UTF-8 to UTF-16LE
+BRANDING_FILES_CONV = \
+	branding.nsi \
+	$(NULL)
+
 BRANDING_FILES = \
-	branding.nsi \
 	wizHeader.bmp \
 	wizHeaderRTL.bmp \
 	wizWatermark.bmp \
 	$(NULL)
 
 DEFINES += \
 	-DAB_CD=$(AB_CD) \
 	-DPKG_BASENAME="$(PKG_BASENAME)" \
 	-DPKG_INST_BASENAME="$(PKG_INST_BASENAME)" \
 	-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
 	-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
 	-DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME} \
 	-DMOZILLA_VERSION=${MOZILLA_VERSION} \
 	$(NULL)
 
 include $(topsrcdir)/config/config.mk
-include $(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/installer/windows/charset.mk
 
 installer::
 	$(MAKE) -C .. installer-stage
 	$(MAKE) $(CONFIG_DIR)/setup.exe
 
 # For building the uninstaller during the application build so it can be
 # included for mar file generation.
 uninstaller::
 	$(RM) -rf $(CONFIG_DIR) && mkdir $(CONFIG_DIR)
+	for i in $(INSTALLER_FILES_CONV); do \
+	  iconv -f UTF-8 -t UTF-16LE $(srcdir)/$$i | \
+	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
+	    $(CONFIG_DIR)/`basename $$i`; \
+	done
 	$(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR)
+	for i in $(BRANDING_FILES_CONV); do \
+	  iconv -f UTF-8 -t UTF-16LE $(DIST)/branding/$$i | \
+	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
+	    $(CONFIG_DIR)/$$i; \
+	done
 	$(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR)
 	$(EXIT_ON_ERROR) \
 	for i in $(PP_LOCALIZED_FILES); do \
 	  $(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $(srcdir)/$$i > $(CONFIG_DIR)/$$i; \
 	done
 	$(PERL) $(topsrcdir)/config/preprocessor.pl -Fsubstitution $(DEFINES) $(ACDEFINES) \
-	  $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi
+	  $(srcdir)/nsis/defines.nsi.in | iconv -f UTF-8 -t UTF-16LE | \
+	  cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
+	  $(CONFIG_DIR)/defines.nsi
 	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl \
 	  $(topsrcdir) $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) \
-	  $(WIN_INSTALLER_CHARSET) $(CONFIG_DIR)
+	  $(CONFIG_DIR)
 
 $(CONFIG_DIR)/setup.exe::
 	$(RM) -rf $(CONFIG_DIR) && mkdir $(CONFIG_DIR)
+	for i in $(INSTALLER_FILES_CONV); do \
+	  iconv -f UTF-8 -t UTF-16LE $(srcdir)/$$i | \
+	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
+	    $(CONFIG_DIR)/`basename $$i`; \
+	done
 	$(INSTALL) $(addprefix $(srcdir)/,$(INSTALLER_FILES)) $(CONFIG_DIR)
+	for i in $(BRANDING_FILES_CONV); do \
+	  iconv -f UTF-8 -t UTF-16LE $(DIST)/branding/$$i | \
+	    cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
+	    $(CONFIG_DIR)/$$i; \
+	done
 	$(INSTALL) $(addprefix $(DIST)/branding/,$(BRANDING_FILES)) $(CONFIG_DIR)
 	$(EXIT_ON_ERROR) \
 	for i in $(PP_LOCALIZED_FILES); do \
 	  $(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $(srcdir)/$$i > $(CONFIG_DIR)/$$i; \
 	done
 	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/make-installremoves.pl \
 	  ../removed-files > $(CONFIG_DIR)/removed-files.log
 	$(PERL) $(topsrcdir)/config/preprocessor.pl -Fsubstitution $(DEFINES) $(ACDEFINES) \
-	  $(srcdir)/nsis/defines.nsi.in > $(CONFIG_DIR)/defines.nsi
+	  $(srcdir)/nsis/defines.nsi.in | iconv -f UTF-8 -t UTF-16LE | \
+	  cat $(MOZILLA_DIR)/toolkit/mozapps/installer/windows/nsis/utf16-le-bom.bin - > \
+	  $(CONFIG_DIR)/defines.nsi
 	$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.pl \
 	  $(topsrcdir) $(call EXPAND_LOCALE_SRCDIR,browser/locales)/installer $(AB_CD) \
-	  $(WIN_INSTALLER_CHARSET) $(CONFIG_DIR)
+	  $(CONFIG_DIR)
 
 include $(topsrcdir)/config/rules.mk
 include $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/makensis.mk
 
 export::
 ifndef MOZ_BRANDING_DIRECTORY
 	$(NSINSTALL) -D $(DIST)/branding
 	cp $(srcdir)/nsis/branding.nsi $(DIST)/branding/branding.nsi
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -47,25 +47,16 @@
 SetDatablockOptimize on
 SetCompress off
 CRCCheck on
 
 RequestExecutionLevel user
 
 !addplugindir ./
 
-; empty files - except for the comment line - for generating custom pages.
-!system 'echo ; > options.ini'
-!system 'echo ; > shortcuts.ini'
-!system 'echo ; > summary.ini'
-
-; USE_UAC_PLUGIN is temporary until all applications have been updated to use
-; the UAC plugin
-!define USE_UAC_PLUGIN
-
 Var TmpVal
 Var StartMenuDir
 Var InstallType
 Var AddStartMenuSC
 Var AddQuickLaunchSC
 Var AddDesktopSC
 
 ; Other included files may depend upon these includes!
@@ -91,22 +82,26 @@ Var AddDesktopSC
 !include version.nsh
 
 VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
 VIAddVersionKey "OriginalFilename" "setup.exe"
 
 ; Must be inserted before other macros that use logging
 !insertmacro _LoggingCommon
 
+; Most commonly used macros for managing shortcuts
+!insertmacro _LoggingShortcutsCommon
+
 !insertmacro AddDDEHandlerValues
 !insertmacro ChangeMUIHeaderImage
 !insertmacro CheckForFilesInUse
 !insertmacro CleanUpdatesDir
 !insertmacro CopyFilesFromDir
 !insertmacro CreateRegKey
+!insertmacro FindSMProgramsDir
 !insertmacro GetPathFromString
 !insertmacro GetParent
 !insertmacro IsHandlerForInstallDir
 !insertmacro ManualCloseAppPrompt
 !insertmacro RegCleanAppHandler
 !insertmacro RegCleanMain
 !insertmacro RegCleanUninstall
 !insertmacro SetBrandNameVars
@@ -126,20 +121,16 @@ VIAddVersionKey "OriginalFilename" "setu
 !insertmacro PreDirectoryCommon
 
 Name "${BrandFullName}"
 OutFile "setup.exe"
 InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
 InstallDir "$PROGRAMFILES\${BrandFullName}\"
 ShowInstDetails nevershow
 
-ReserveFile options.ini
-ReserveFile shortcuts.ini
-ReserveFile summary.ini
-
 ################################################################################
 # Modern User Interface - MUI
 
 !define MUI_ABORTWARNING
 !define MUI_ICON setup.ico
 !define MUI_UNICON setup.ico
 !define MUI_WELCOMEPAGE_TITLE_3LINES
 !define MUI_HEADERIMAGE
@@ -171,19 +162,16 @@ Page custom preOptions leaveOptions
 
 ; Custom Shortcuts Page
 Page custom preShortcuts leaveShortcuts
 
 ; Start Menu Folder Page Configuration
 !define MUI_PAGE_CUSTOMFUNCTION_PRE preStartMenu
 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE leaveStartMenu
 !define MUI_STARTMENUPAGE_NODISABLE
-!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
-!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
-!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
 !insertmacro MUI_PAGE_STARTMENU Application $StartMenuDir
 
 ; Custom Summary Page
 Page custom preSummary leaveSummary
 
 ; Install Files Page
 !insertmacro MUI_PAGE_INSTFILES
 
@@ -250,17 +238,17 @@ Section "-Application" APP_IDX
   RegDLL "$INSTDIR\AccessibleMarshal.dll"
   ${If} ${Errors}
     ${LogMsg} "** ERROR Registering: $INSTDIR\AccessibleMarshal.dll **"
   ${Else}
     ${LogUninstall} "DLLReg: \AccessibleMarshal.dll"
     ${LogMsg} "Registered: $INSTDIR\AccessibleMarshal.dll"
   ${EndIf}
 
-  ; Write extra files created by the application to the uninstall.log so they
+  ; Write extra files created by the application to the uninstall log so they
   ; will be removed when the application is uninstalled. To remove an empty
   ; directory write a bogus filename to the deepest directory and all empty
   ; parent directories will be removed.
   ${LogUninstall} "File: \components\compreg.dat"
   ${LogUninstall} "File: \components\xpti.dat"
   ${LogUninstall} "File: \.autoreg"
   ${LogUninstall} "File: \active-update.xml"
   ${LogUninstall} "File: \install.log"
@@ -348,21 +336,16 @@ Section "-Application" APP_IDX
 
   ; The order that reg keys and values are added is important if you use the
   ; uninstall log to remove them on uninstall. When using the uninstall log you
   ; MUST add children first so they will be removed first on uninstall so they
   ; will be empty when the key is deleted. This allows the uninstaller to
   ; specify that only empty keys will be deleted.
   ${SetAppKeys}
 
-  ; XXXrstrong - this should be set in shared.nsh along with "Create Quick
-  ; Launch Shortcut" and Create Desktop Shortcut.
-  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
-  ${WriteRegDWORD2} $TmpVal "$0" "Create Start Menu Shortcut" $AddStartMenuSC 0
-
   ${FixClassKeys}
 
   ; On install always add the FirefoxHTML and FirefoxURL keys.
   ; An empty string is used for the 5th param because FirefoxHTML and FirefoxURL
   ; are not protocol handlers.
   ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
   StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
   StrCpy $3 "$\"%1$\",,0,0,,,,"
@@ -401,41 +384,47 @@ Section "-Application" APP_IDX
   ${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0
   ${WriteRegStr2} $TmpVal "$0" "Path" "$INSTDIR" 0
 
   StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9"
   ${CreateRegKey} "$TmpVal" "$0" 0
 
   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
 
-  ; Create Start Menu shortcuts
+  ; Create shortcuts
   ${LogHeader} "Adding Shortcuts"
+
+  ; Always add the relative path to the application's Start Menu directory and
+  ; the application's shortcuts to the shortcuts log ini file. The
+  ; DeleteShortcuts macro will do the right thing on uninstall if they don't
+  ; exist.
+  ${LogSMProgramsDirRelPath} "$StartMenuDir"
+  ${LogSMProgramsShortcut} "${BrandFullName}.lnk"
+  ${LogSMProgramsShortcut} "${BrandFullName} ($(SAFE_MODE)).lnk"
+  ${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
+  ${LogDesktopShortcut} "${BrandFullName}.lnk"
+
   ${If} $AddStartMenuSC == 1
     ${Unless} ${FileExists} "$SMPROGRAMS\$StartMenuDir"
       CreateDirectory "$SMPROGRAMS\$StartMenuDir"
       ${LogMsg} "Added Start Menu Directory: $SMPROGRAMS\$StartMenuDir"
     ${EndUnless}
-    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal}.lnk"
-    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal}.lnk"
-    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal} ($(SAFE_MODE)).lnk" "$INSTDIR\${FileMainEXE}" "-safe-mode" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal} ($(SAFE_MODE)).lnk"
-    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal} ($(SAFE_MODE)).lnk"
+    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
+    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk"
+    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk" "$INSTDIR\${FileMainEXE}" "-safe-mode" "$INSTDIR\${FileMainEXE}" 0
+    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk"
   ${EndIf}
 
-  ; perhaps use the uninstall keys
   ${If} $AddQuickLaunchSC == 1
     CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $QUICKLAUNCH\${BrandFullName}.lnk"
     ${LogMsg} "Added Shortcut: $QUICKLAUNCH\${BrandFullName}.lnk"
   ${EndIf}
 
   ${If} $AddDesktopSC == 1
     CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $DESKTOP\${BrandFullName}.lnk"
     ${LogMsg} "Added Shortcut: $DESKTOP\${BrandFullName}.lnk"
   ${EndIf}
 
   !insertmacro MUI_STARTMENU_WRITE_END
 SectionEnd
 
 ; Cleanup operations to perform at the end of the installation.
 Section "-InstallEndCleanup"
@@ -643,16 +632,42 @@ Function leaveShortcuts
     Abort
   ${EndIf}
   ${MUI_INSTALLOPTIONS_READ} $AddDesktopSC "shortcuts.ini" "Field 2" "State"
   ${MUI_INSTALLOPTIONS_READ} $AddStartMenuSC "shortcuts.ini" "Field 3" "State"
   ${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State"
 FunctionEnd
 
 Function preStartMenu
+  ; With the Unicode installer the path to the application's Start Menu
+  ; directory relative to the Start Menu's Programs directory is written to the
+  ; shortcuts log ini file and is used to set the default Start Menu directory.
+  ${GetSMProgramsDirRelPath} $0
+  ${If} "$0" != ""
+    StrCpy $StartMenuDir "$0"
+  ${Else}
+    ; Prior to the Unicode installer the path to the application's Start Menu
+    ; directory relative to the Start Menu's Programs directory was written to
+    ; the registry and use this value to set the default Start Menu directory.
+    ClearErrors
+    ReadRegStr $0 HKLM "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main" "Start Menu Folder"
+    ${If} ${Errors}
+      ; Use the FindSMProgramsDir macro to find a previously used path to the
+      ; application's Start Menu directory relative to the Start Menu's Programs
+      ; directory in the uninstall log and use this value to set the default
+      ; Start Menu directory.
+      ${FindSMProgramsDir} $0
+      ${If} "$0" != ""
+        StrCpy $StartMenuDir "$0"
+      ${EndIf}
+    ${Else}
+      StrCpy $StartMenuDir "$0"
+    ${EndUnless}
+  ${EndIf}
+
   ${CheckCustomCommon}
   ${If} $AddStartMenuSC != 1
     Abort
   ${EndIf}
 FunctionEnd
 
 Function leaveStartMenu
   ${If} $InstallType == ${INSTALLTYPE_CUSTOM}
@@ -757,19 +772,19 @@ FunctionEnd
 # Initialization Functions
 
 Function .onInit
   StrCpy $LANGUAGE 0
   ${SetBrandNameVars} "$EXEDIR\localized\distribution\setup.ini"
 
   ${InstallOnInitCommon} "$(WARN_MIN_SUPPORTED_OS_MSG)"
 
-  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "options.ini"
-  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "shortcuts.ini"
-  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "summary.ini"
+  !insertmacro InitInstallOptionsFile "options.ini"
+  !insertmacro InitInstallOptionsFile "shortcuts.ini"
+  !insertmacro InitInstallOptionsFile "summary.ini"
 
   ; Setup the options.ini file for the Custom Options Page
   WriteINIStr "$PLUGINSDIR\options.ini" "Settings" NumFields "6"
 
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Type   "label"
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Text   "$(OPTIONS_SUMMARY)"
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Left   "0"
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Right  "-1"
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -30,16 +30,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 !macro PostUpdate
+  ${CreateShortcutsLog}
+
   ; Remove registry entries for non-existent apps and for apps that point to our
   ; install location in the Software\Mozilla key and uninstall registry entries
   ; that point to our install location for both HKCU and HKLM.
   SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   ${RegCleanMain} "Software\Mozilla"
   ${RegCleanUninstall}
   ${UpdateProtocolHandlers}
 
@@ -348,61 +350,16 @@
 
 !macro SetAppKeys
   ${GetLongPath} "$INSTDIR" $8
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
   ${WriteRegStr2} $TmpVal "$0" "Install Directory" "$8" 0
   ${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0
   ${WriteRegStr2} $TmpVal "$0" "Program Folder Path" "$SMPROGRAMS\$StartMenuDir" 0
 
-  SetShellVarContext all  ; Set $DESKTOP to All Users
-  ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
-    SetShellVarContext current  ; Set $DESKTOP to the current user's desktop
-  ${EndUnless}
-
-  ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
-    ShellLink::GetShortCutArgs "$DESKTOP\${BrandFullName}.lnk"
-    Pop $1
-    ${If} "$1" == ""
-      ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
-      Pop $1
-      ${GetLongPath} "$1" $1
-      ${If} "$1" == "$8\${FileMainEXE}"
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" 1 0
-      ${Else}
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" 0 0
-      ${EndIf}
-    ${EndIf}
-  ${EndIf}
-
-  ; XXXrstrong - need a cleaner way to prevent unsetting SHCTX from HKLM when
-  ; trying to find the desktop shortcut.
-  ${If} "$TmpVal" == "HKCU"
-    SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU)
-  ${Else}
-    SetShellVarContext all     ; Set SHCTX to all users (e.g. HKLM)
-  ${EndIf}
-
-  ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
-    ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk"
-    Pop $1
-    ${If} "$1" == ""
-      ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk"
-      Pop $1
-      ${GetLongPath} "$1" $1
-      ${If} "$1" == "$8\${FileMainEXE}"
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" 1 0
-      ${Else}
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" 0 0
-      ${EndIf}
-    ${EndIf}
-  ${EndIf}
-  ; XXXrstrong - "Create Start Menu Shortcut" and "Start Menu Folder" are only
-  ; set in the installer and should also be set here for software update.
-
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
   ${WriteRegStr2} $TmpVal "$0" "Uninstall Log Folder" "$8\uninstall" 0
   ${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} (${AppVersion})" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})"
   ${WriteRegStr2} $TmpVal  "$0" "" "${AppVersion} (${AB_CD})" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\bin"
@@ -544,16 +501,45 @@
   StrCpy $0 "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\gopher"
   ReadRegStr $2 HKCU "$0\UserChoice" "Progid"
   ${If} "$2" == "FirefoxURL"
     DeleteRegKey HKCU "$0"
   ${EndIf}
 !macroend
 !define RemoveDeprecatedKeys "!insertmacro RemoveDeprecatedKeys"
 
+; Creates the shortcuts log ini file with the appropriate entries if it doesn't
+; already exist.
+!macro CreateShortcutsLog
+  ${GetShortcutsLogPath} $0
+  ${Unless} ${FileExists} "$0"
+    ; Default to ${BrandFullName} for the Start Menu Folder
+    StrCpy $TmpVal ${BrandFullName}
+    ; Prior to Firefox 3.1 the Start Menu directory was written to the registry and
+    ; this value can be used to set the Start Menu directory.
+    ClearErrors
+    ReadRegStr $0 SHCTX "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main" "Start Menu Folder"
+    ${If} ${Errors}
+      ${FindSMProgramsDir} $0
+      ${If} "$0" != ""
+        StrCpy $TmpVal "$0"
+      ${EndIf}
+    ${Else}
+      StrCpy $TmpVal "$0"
+    ${EndUnless}
+
+    ${LogSMProgramsDirRelPath} "$TmpVal"
+    ${LogSMProgramsShortcut} "${BrandFullName}.lnk"
+    ${LogSMProgramsShortcut} "${BrandFullName} ($(SAFE_MODE)).lnk"
+    ${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
+    ${LogDesktopShortcut} "${BrandFullName}.lnk"
+  ${EndUnless}
+!macroend
+!define CreateShortcutsLog "!insertmacro CreateShortcutsLog"
+
 ; The files to check if they are in use during (un)install so the restart is
 ; required message is displayed. All files must be located in the $INSTDIR
 ; directory.
 !macro PushFilesToCheck
   ; The first string to be pushed onto the stack MUST be "end" to indicate
   ; that there are no more files to check in $INSTDIR and the last string
   ; should be ${FileMainEXE} so if it is in use the CheckForFilesInUse macro
   ; returns after the first check.
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -47,20 +47,16 @@
 SetDatablockOptimize on
 SetCompress off
 CRCCheck on
 
 RequestExecutionLevel user
 
 !addplugindir ./
 
-; USE_UAC_PLUGIN is temporary until all applications have been updated to use
-; the UAC plugin
-!define USE_UAC_PLUGIN
-
 ; prevents compiling of the reg write logging.
 !define NO_LOG
 
 Var TmpVal
 
 ; Other included files may depend upon these includes!
 ; The following includes are provided by NSIS.
 !include FileFunc.nsh
@@ -82,34 +78,39 @@ Var TmpVal
 !include locales.nsi
 !include version.nsh
 
 ; This is named BrandShortName helper because we use this for software update
 ; post update cleanup.
 VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
 VIAddVersionKey "OriginalFilename" "helper.exe"
 
+; Most commonly used macros for managing shortcuts
+!insertmacro _LoggingShortcutsCommon
+
 !insertmacro AddDDEHandlerValues
 !insertmacro CleanVirtualStore
+!insertmacro FindSMProgramsDir
 !insertmacro GetLongPath
 !insertmacro GetPathFromString
 !insertmacro IsHandlerForInstallDir
 !insertmacro RegCleanAppHandler
 !insertmacro RegCleanMain
 !insertmacro RegCleanUninstall
 !insertmacro SetBrandNameVars
 !insertmacro UnloadUAC
 !insertmacro WriteRegDWORD2
 !insertmacro WriteRegStr2
 
 !insertmacro un.ChangeMUIHeaderImage
 !insertmacro un.CheckForFilesInUse
 !insertmacro un.CleanUpdatesDir
 !insertmacro un.CleanVirtualStore
 !insertmacro un.DeleteRelativeProfiles
+!insertmacro un.DeleteShortcuts
 !insertmacro un.GetLongPath
 !insertmacro un.GetSecondInstallPath
 !insertmacro un.ManualCloseAppPrompt
 !insertmacro un.ParseUninstallLog
 !insertmacro un.RegCleanAppHandler
 !insertmacro un.RegCleanFileHandler
 !insertmacro un.RegCleanMain
 !insertmacro un.RegCleanUninstall
@@ -212,27 +213,29 @@ Section "Uninstall"
     RmDir "$APPDATA\Mozilla\Extensions\{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
     RmDir "$APPDATA\Mozilla\Extensions"
     RmDir "$APPDATA\Mozilla"
   ${EndIf}
 
   SetShellVarContext current  ; Set SHCTX to HKCU
   ${un.RegCleanMain} "Software\Mozilla"
   ${un.RegCleanUninstall}
+  ${un.DeleteShortcuts}
 
   ClearErrors
   WriteRegStr HKLM "Software\Mozilla\InstallerTest" "InstallerTest" "Test"
   ${If} ${Errors}
     StrCpy $TmpVal "HKCU" ; used primarily for logging
   ${Else}
     SetShellVarContext all  ; Set SHCTX to HKLM
     DeleteRegKey HKLM "Software\Mozilla\InstallerTest"
     StrCpy $TmpVal "HKLM" ; used primarily for logging
     ${un.RegCleanMain} "Software\Mozilla"
     ${un.RegCleanUninstall}
+    ${un.DeleteShortcuts}
   ${EndIf}
 
   ${un.RegCleanAppHandler} "FirefoxURL"
   ${un.RegCleanAppHandler} "FirefoxHTML"
   ${un.RegCleanProtocolHandler} "ftp"
   ${un.RegCleanProtocolHandler} "http"
   ${un.RegCleanProtocolHandler} "https"
 
@@ -563,16 +566,18 @@ Function un.onInit
   ${EndUnless}
 
   StrCpy $LANGUAGE 0
   ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
 
   ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
   ; the user clicks the back button
   StrCpy $hHeaderBitmap ""
+
+  !insertmacro InitInstallOptionsFile "unconfirm.ini"
 FunctionEnd
 
 Function .onGUIEnd
   ${OnEndCommon}
 FunctionEnd
 
 Function un.onGUIEnd
   ${un.OnEndCommon}
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -332,16 +332,19 @@ bin\res\charsetalias.properties
 bin\res\charsetData.properties
 bin\res\langGroups.properties
 bin\res\language.properties
 bin\res\entityTables\*
 
 ; svg
 bin\res\svg.css
 bin\components\dom_svg.xpt
+#ifdef MOZ_SMIL
+bin\components\dom_smil.xpt
+#endif
 
 ; [Personal Security Manager]
 ;
 bin\nssckbi.dll
 bin\components\pipboot.xpt
 bin\components\pipnss.xpt
 bin\components\pippki.xpt
 bin\nssutil3.dll
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -1083,16 +1083,21 @@ toolbar[iconsize="small"] #paste-button[
 #editBookmarkPanelStarIcon[unstarred] {
   list-style-image: url("chrome://browser/skin/places/unstarred48.png");
 }
 
 #editBookmarkPanelTitle {
   font-size: 130%;
 }
 
+/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+#editBMPanel_folderTree {
+  min-width: 300px;
+}
+
 /* Content area */
 #sidebar {
   background-color: Window;
 }
 
 #status-bar {
   border-top: none;
 }
--- a/browser/themes/gnomestripe/browser/places/editBookmarkOverlay.css
+++ b/browser/themes/gnomestripe/browser/places/editBookmarkOverlay.css
@@ -71,19 +71,23 @@
 .expander-down:hover:active {
 	list-style-image: url("chrome://global/skin/arrow/arrow-dn-hov.gif");
 }
 
 .expander-up:hover:active {
 	list-style-image: url("chrome://global/skin/arrow/arrow-up-hov.gif");
 }
 
-#editBMPanel_tagsSelector[collapsed="true"],
-#editBMPanel_folderTree[collapsed="true"] {
-  display: none;
+#editBookmarkPanelContent {
+  min-width: 260px;
+}
+
+#editBMPanel_folderTree {
+  margin-top: 2px;
+  margin-bottom: 2px;
 }
 
 /**** name picker ****/
 
 /* Make the microsummary picker look like a regular textbox instead of 
  * an editable menulist when no microsummaries are available.
  */
 #editBMPanel_namePicker[droppable="false"] {
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -1083,19 +1083,18 @@ richlistitem[selected="true"][current="t
   background-image: url("chrome://browser/skin/hud-style-new-folder-bar-background.png");
   background-repeat: repeat-x;
   border: 0;
   border-width: 1px 0 1px 0;
   border-style: solid;
   border-top-color: #212121;
   border-bottom-color: #212121;
   padding: 0;
-  margin: 0;
-  -moz-margin-start: -8px;
-  -moz-margin-end: -8px;
+  margin-left: 4px;
+  margin-right: 4px;
   margin-bottom: 8px !important;
   height:  20px;
 }
 
 #editBookmarkPanel #editBMPanel_newFolderButton {
   -moz-appearance: none;
   background-color: transparent !important;
   border: 0;
@@ -1169,20 +1168,19 @@ richlistitem[selected="true"][current="t
 
 #editBookmarkPanel #editBMPanel_folderTree {
   background-color: #333333;
   border-top: 2px solid !important;
   border-right: 0 !important;
   border-bottom: 0 !important;
   border-left: 0 !important;
   -moz-border-top-colors: rgba(0,0,0,0.35) rgba(255,255,255,0.15);
-  margin: 0px;
-  -moz-margin-start: -8px;
-  -moz-margin-end: -8px;
   color: #ffffff !important;
+  /* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+  min-width: 300px;
 }
 
 #editBookmarkPanel #editBMPanel_folderTree:focus {
   outline: 2px solid -moz-mac-focusring;
   outline-offset: -1px;
   -moz-outline-radius: 1px;
 }
 
@@ -1213,17 +1211,16 @@ richlistitem[selected="true"][current="t
   -moz-appearance: none;
   background-color: #333333;
   border-top: 2px solid !important;
   border-right: 0 !important;
   border-bottom: 2px solid !important;
   border-left: 0 !important;
   -moz-border-top-colors: rgba(0,0,0,0.35) rgba(255,255,255,0.15);
   -moz-border-bottom-colors: rgba(255,255,255,0.30) rgba(0,0,0,0.35) ;
-  margin: 6px -8px !important;
   color: #ffffff !important;
 }
 
 #editBookmarkPanel #editBMPanel_tagsSelector:focus {
   outline: 2px solid -moz-mac-focusring;
   outline-offset: -2px;
   -moz-outline-radius: 1px;
 }
@@ -1470,16 +1467,20 @@ sidebarheader > .tabs-closebutton > .too
 #wrapper-navigator-throbber > #navigator-throbber {
   list-style-image: url("chrome://global/skin/icons/notloading_16.png");
 }
 
 toolbarbutton.chevron {
   list-style-image: url("chrome://global/skin/icons/chevron.png") !important;
 }
 
+toolbarbutton.chevron[chromedir="rtl"] {
+  list-style-image: url("chrome://global/skin/icons/chevron-rtl.png") !important;
+}
+
 
 toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
 #nav-bar {
   background-color: #9e9e9e;
   background-image: url("chrome://global/skin/toolbar/toolbar-background.gif");
--- a/browser/themes/pinstripe/browser/places/editBookmarkOverlay.css
+++ b/browser/themes/pinstripe/browser/places/editBookmarkOverlay.css
@@ -52,27 +52,22 @@
 .folder-icon {
   list-style-image: url("chrome://global/skin/tree/folder.png") !important;
 }
 
 .menulist-icon {
 	margin: 0 !important;
 }
 
-/**** folder tree ****/
-
-#editBMPanel_folderTree {
-   margin: 6px 0;
-}
-
 /**** expanders ****/
 
 .expander-up,
 .expander-down {
   -moz-appearance: none;
+  margin: 0;
   margin-left: 8px;
   padding: 0;
   min-width: 0;
 }
 
 .expander-up {
 	list-style-image: url("chrome://browser/skin/places/expander-open.png") !important;
 }
@@ -84,16 +79,24 @@
 .expander-down:hover:active {
 	list-style-image: url("chrome://browser/skin/places/expander-closed-active.png") !important;
 }
 
 .expander-up:hover:active {
 	list-style-image: url("chrome://browser/skin/places/expander-open-active.png") !important;
 }
 
+#editBookmarkPanelContent {
+  min-width: 260px;
+}
+
+#editBMPanel_folderTree {
+  margin: 6px 4px 0 4px;
+}
+
 /**** name picker ****/
 
 /* Make the microsummary picker look like a regular textbox instead of 
  * an editable menulist when no microsummaries are available.
  */
 #editBMPanel_namePicker[droppable="false"] {
   -moz-appearance: none;
   margin: 0px;
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1222,16 +1222,21 @@ statusbarpanel#statusbar-display {
 #editBookmarkPanelStarIcon[unstarred] {
   list-style-image: url("chrome://browser/skin/places/unstarred48.png");
 }
 
 #editBookmarkPanelTitle {
   font-size: 130%;
 }
 
+/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+#editBMPanel_folderTree {
+  min-width: 300px;
+}
+
 /* ::::: content area ::::: */
 
 #sidebar {
   background-color: Window;
 }
 
 #sidebar-title {
   -moz-padding-start: 0px;
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -139,17 +139,17 @@ classic.jar:
         skin/classic/aero/browser/feeds/feed-icons-16.png            (feeds/feed-icons-16-aero.png)
         skin/classic/aero/browser/feeds/feedIcon.png                 (feeds/feedIcon-aero.png)
         skin/classic/aero/browser/feeds/feedIcon16.png               (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/feeds/audioFeedIcon.png            (feeds/audioFeedIcon-aero.png)
         skin/classic/aero/browser/feeds/audioFeedIcon16.png          (feeds/audioFeedIcon16-aero.png)
         skin/classic/aero/browser/feeds/videoFeedIcon.png            (feeds/videoFeedIcon-aero.png)
         skin/classic/aero/browser/feeds/videoFeedIcon16.png          (feeds/videoFeedIcon16-aero.png)
         skin/classic/aero/browser/feeds/subscribe.css                (feeds/subscribe.css)
-        skin/classic/aero/browser/places/places.css                  (places/places.css)
+*       skin/classic/aero/browser/places/places.css                  (places/places-aero.css)
 *       skin/classic/aero/browser/places/organizer.css               (places/organizer-aero.css)
         skin/classic/aero/browser/places/bookmark.png                (places/bookmark-aero.png)
         skin/classic/aero/browser/places/editBookmark.png            (places/editBookmark-aero.png)
         skin/classic/aero/browser/places/query.png                   (places/query-aero.png)
         skin/classic/aero/browser/places/bookmarksMenu.png           (places/bookmarksMenu-aero.png)
         skin/classic/aero/browser/places/bookmarksToolbar.png        (places/bookmarksToolbar-aero.png)
         skin/classic/aero/browser/places/calendar.png                (places/calendar-aero.png)
         skin/classic/aero/browser/places/dropDown.png                (places/dropDown-aero.png)
--- a/browser/themes/winstripe/browser/places/editBookmarkOverlay.css
+++ b/browser/themes/winstripe/browser/places/editBookmarkOverlay.css
@@ -52,34 +52,39 @@
 
 
 /**** expanders ****/
 
 .expander-up,
 .expander-down {
   min-width: 0;
   margin: 0;
+  -moz-margin-end: 4px;
 }
 
 .expander-up > hbox,
 .expander-down > hbox {
   padding: 0;
 }
 
 .expander-up {
   list-style-image: url("chrome://global/skin/icons/collapse.png");
 }
 
 .expander-down {
   list-style-image: url("chrome://global/skin/icons/expand.png");
 }
 
-#editBMPanel_tagsSelector[collapsed="true"],
-#editBMPanel_folderTree[collapsed="true"] {
-  display: none;
+#editBookmarkPanelContent {
+  min-width: 260px;
+}
+
+#editBMPanel_folderTree {
+  margin-top: 2px;
+  margin-bottom: 2px;
 }
 
 /**** name picker ****/
 
 /* Make the microsummary picker look like a regular textbox instead of 
  * an editable menulist when no microsummaries are available.
  */
 #editBMPanel_namePicker[droppable="false"] {
new file mode 100644
--- /dev/null
+++ b/browser/themes/winstripe/browser/places/places-aero.css
@@ -0,0 +1,12 @@
+%include places.css
+
+/* Style Places sidebars as Vista media collection */
+#bookmarksPanel:-moz-system-metric(windows-default-theme),
+#history-panel:-moz-system-metric(windows-default-theme) {
+  background-color: #EEF3FA;
+}
+
+.sidebar-placesTree:-moz-system-metric(windows-default-theme) {
+  background-color: transparent;
+  border-top: none;
+}
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -104,16 +104,22 @@ AUTOMATION_PPARGS += -DIS_CYGWIN=1
 endif
 
 ifeq ($(ENABLE_TESTS), 1)
 AUTOMATION_PPARGS += -DIS_TEST_BUILD=1
 else
 AUTOMATION_PPARGS += -DIS_TEST_BUILD=0
 endif
 
+ifeq ($(MOZ_DEBUG), 1)
+AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=1
+else
+AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=0
+endif
+
 _LEAKTEST_DIR = $(DEPTH)/_leaktest
 
 _LEAKTEST_FILES =    \
 		automation.py \
 		leaktest.py \
 		bloatcycle.html \
 		$(topsrcdir)/build/pgo/server-locations.txt \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/build/autoconf/moznbytetype.m4
@@ -0,0 +1,73 @@
+dnl ***** BEGIN LICENSE BLOCK *****
+dnl Version: MPL 1.1/GPL 2.0/LGPL 2.1
+dnl
+dnl The contents of this file are subject to the Mozilla Public License Version
+dnl 1.1 (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl http://www.mozilla.org/MPL/
+dnl
+dnl Software distributed under the License is distributed on an "AS IS" basis,
+dnl WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+dnl for the specific language governing rights and limitations under the
+dnl License.
+dnl
+dnl The Original Code is mozilla.org code.
+dnl
+dnl The Initial Developer of the Original Code is
+dnl   The Mozilla Foundation
+dnl Portions created by the Initial Developer are Copyright (C) 2008
+dnl the Initial Developer. All Rights Reserved.
+dnl
+dnl Contributor(s):
+dnl   Jim Blandy
+dnl
+dnl Alternatively, the contents of this file may be used under the terms of
+dnl either of the GNU General Public License Version 2 or later (the "GPL"),
+dnl or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+dnl in which case the provisions of the GPL or the LGPL are applicable instead
+dnl of those above. If you wish to allow use of your version of this file only
+dnl under the terms of either the GPL or the LGPL, and not to allow others to
+dnl use your version of this file under the terms of the MPL, indicate your
+dnl decision by deleting the provisions above and replace them with the notice
+dnl and other provisions required by the GPL or the LGPL. If you do not delete
+dnl the provisions above, a recipient may use your version of this file under
+dnl the terms of any one of the MPL, the GPL or the LGPL.
+dnl
+dnl ***** END LICENSE BLOCK *****
+
+dnl MOZ_N_BYTE_TYPE(TYPENAME, SIZE, POSSIBLE-TYPES)
+dnl
+dnl Check to see which of POSSIBLE-TYPES has a size of SIZE.  If we
+dnl find one, define TYPENAME to be the size-BYTE type.  If no type
+dnl matches, exit the configure script with an error message.  Types
+dnl whose written form contains spaces should appear in POSSIBLE-TYPES
+dnl enclosed by shell quotes.
+dnl
+dnl The cache variable moz_cv_n_byte_type_TYPENAME gets set to the
+dnl type, if found.
+dnl 
+dnl for example:
+dnl MOZ_N_BYTE_TYPE([JS_INT32_T], [4], [int long 'long long' short])
+dnl
+AC_DEFUN(MOZ_N_BYTE_TYPE,
+[
+dnl The simplest approach would simply be to run a program that says
+dnl   printf ("%d\n", sizeof ($type));
+dnl But that won't work when cross-compiling; this will.
+AC_CACHE_CHECK([for a $2-byte type], moz_cv_n_byte_type_$1, [
+  moz_cv_n_byte_type_$1=
+  for type in $3; do
+    AC_TRY_COMPILE([],
+                   [
+                     int a[sizeof ($type) == $2 ? 1 : -1];
+                     return;
+                   ],
+                   [moz_cv_n_byte_type_$1=$type; break], [])
+  done
+  if ! test "$moz_cv_n_byte_type_$1"; then
+    AC_MSG_ERROR([Couldn't find a $2-byte type])
+  fi
+])
+AC_DEFINE_UNQUOTED($1, [$moz_cv_n_byte_type_$1],
+                   [a $2-byte type on the target machine])
+])
--- a/build/leaktest.py.in
+++ b/build/leaktest.py.in
@@ -77,11 +77,13 @@ if __name__ == '__main__':
     browserEnv["NO_EM_RESTART"] = "1"
     if not "XPCOM_DEBUG_BREAK" in browserEnv:
         browserEnv["XPCOM_DEBUG_BREAK"] = "stack"
     if automation.UNIXISH:
         browserEnv["LD_LIBRARY_PATH"] = os.path.join(SCRIPT_DIR, DIST_BIN)
         browserEnv["MOZILLA_FIVE_HOME"] = os.path.join(SCRIPT_DIR, DIST_BIN)
         browserEnv["GNOME_DISABLE_CRASH_DIALOG"] = "1"
 
-    automation.runApp("http://localhost:%d/bloatcycle.html" % PORT, browserEnv,
-                      os.path.join(SCRIPT_DIR, automation.DEFAULT_APP),
-                      PROFILE_DIRECTORY, extraArgs)
+    url = "http://localhost:%d/bloatcycle.html" % PORT
+    appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)
+    (status, start) = automation.runApp(url, browserEnv, appPath,
+                                        PROFILE_DIRECTORY, extraArgs)
+    sys.exit(status)
--- a/build/pgo/Makefile.in
+++ b/build/pgo/Makefile.in
@@ -40,34 +40,36 @@ DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir = build/pgo
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = \
-		certs \
-		$(NULL)
+  blueprint \
+  js-input \
+  certs \
+  $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 # Stuff to make a build with a profile
 _PROFILE_DIR = $(DEPTH)/_profile/pgo
 _CERTS_DIR = $(_PROFILE_DIR)/certs
 _CERTS_SRC_DIR = $(srcdir)/certs
 
 _PGO_FILES = 	\
-		automation.py \
-		profileserver.py \
-		genpgocert.py \
-		index.html \
-		quit.js \
-		server-locations.txt \
-		$(NULL)
+  automation.py \
+  profileserver.py \
+  genpgocert.py \
+  index.html \
+  server-locations.txt \
+  favicon.ico \
+  $(NULL)
 
 ifeq ($(USE_SHORT_LIBNAME), 1)
 PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 else
 PROGRAM = $(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 endif
 
 ifeq ($(MOZ_BUILD_APP),camino)
@@ -109,16 +111,22 @@ AUTOMATION_PPARGS += -DIS_CYGWIN=1
 endif
 
 ifeq ($(ENABLE_TESTS), 1)
 AUTOMATION_PPARGS += -DIS_TEST_BUILD=1
 else
 AUTOMATION_PPARGS += -DIS_TEST_BUILD=0
 endif
 
+ifeq ($(MOZ_DEBUG), 1)
+AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=1
+else
+AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=0
+endif
+
 automation.py: automation.py.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
 	$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
 
 genpgocert.py: genpgocert.py.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
 	$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
 
old mode 100644
new mode 100755
--- a/build/pgo/automation.py.in
+++ b/build/pgo/automation.py.in
@@ -79,16 +79,17 @@ IS_CYGWIN = False
 #expand IS_CAMINO = __IS_CAMINO__ != 0
 #expand BIN_SUFFIX = __BIN_SUFFIX__
 
 UNIXISH = not IS_WIN32 and not IS_MAC
 
 #expand DEFAULT_APP = "./" + __BROWSER_PATH__
 #expand CERTS_DIR = __CERTS_DIR__
 #expand IS_TEST_BUILD = __IS_TEST_BUILD__
+#expand IS_DEBUG_BUILD = __IS_DEBUG_BUILD__
 
 ###########
 # LOGGING #
 ###########
 
 # We use the logging system here primarily because it'll handle multiple
 # threads, which is needed to process the output of the server and application
 # processes simultaneously.
@@ -304,21 +305,30 @@ user_pref("browser.shell.checkDefaultBro
 user_pref("shell.checkDefaultClient", false);
 user_pref("browser.warnOnQuit", false);
 user_pref("accessibility.typeaheadfind.autostart", false);
 user_pref("javascript.options.showInConsole", true);
 user_pref("layout.debug.enable_data_xbl", true);
 user_pref("browser.EULA.override", true);
 user_pref("javascript.options.jit.content", true);
 user_pref("gfx.color_management.force_srgb", true);
+user_pref("network.manage-offline-status", false);
+user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
 
 user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
 """
   prefs.append(part)
 
+  # Increase the max script run time 10-fold for debug builds
+  if (IS_DEBUG_BUILD):
+    prefs.append("""\
+user_pref("dom.max_script_run_time", 100);
+user_pref("dom.max_chrome_script_run_time", 200);
+""")
+
   locations = readLocations()
 
   # Grant God-power to all the privileged servers on which tests run.
   privileged = filter(lambda loc: "privileged" in loc.options, locations)
   for (i, l) in itertools.izip(itertools.count(1), privileged):
     part = """
 user_pref("capability.principal.codebase.p%(i)d.granted",
           "UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite \
@@ -391,43 +401,57 @@ def fillCertificateDB(profileDir):
   sslTunnelConfigPath = os.path.join(CERTS_DIR, "ssltunnel.cfg")
   sslTunnelConfig = open(sslTunnelConfigPath, "w")
   
   sslTunnelConfig.write("httpproxy:1\n")
   sslTunnelConfig.write("certdbdir:%s\n" % CERTS_DIR)
   sslTunnelConfig.write("forward:127.0.0.1:8888\n")
   sslTunnelConfig.write("listen:*:4443:pgo server certificate\n")
 
-  # Generate automatic certificate and bond custom certificates
+  # Configure automatic certificate and bind custom certificates, client authentication
   locations = readLocations()
   locations.pop(0)
   for loc in locations:
     if loc.scheme == "https" and "nocert" not in loc.options:
       customCertRE = re.compile("^cert=(?P<nickname>[0-9a-zA-Z_ ]+)")
+      clientAuthRE = re.compile("^clientauth=(?P<clientauth>[a-z]+)")
       for option in loc.options:
         match = customCertRE.match(option)
         if match:
           customcert = match.group("nickname");
-          sslTunnelConfig.write("listen:%s:%s:4443:%s\n" % (loc.host, loc.port, customcert))
-          break
+          sslTunnelConfig.write("listen:%s:%s:4443:%s\n" %
+              (loc.host, loc.port, customcert))
+
+        match = clientAuthRE.match(option)
+        if match:
+          clientauth = match.group("clientauth");
+          sslTunnelConfig.write("clientauth:%s:%s:4443:%s\n" %
+              (loc.host, loc.port, clientauth))
 
   sslTunnelConfig.close()
 
   # Pre-create the certification database for the profile
   certutil = DIST_BIN + "/certutil" + BIN_SUFFIX
+  pk12util = DIST_BIN + "/pk12util" + BIN_SUFFIX
+
   status = Process(certutil, ["-N", "-d", profileDir, "-f", pwfilePath], environment()).wait()
   if status != 0:
     return status
 
-  # Walk the cert directory and add custom CAs as trusted
+  # Walk the cert directory and add custom CAs and client certs
   files = os.listdir(CERTS_DIR)
   for item in files:
     root, ext = os.path.splitext(item)
     if ext == ".ca":
-      Process(certutil, ["-A", "-i", os.path.join(CERTS_DIR, item), "-d", profileDir, "-f", pwfilePath, "-n", root, "-t", "CT,,"], environment())
+      Process(certutil, ["-A", "-i", os.path.join(CERTS_DIR, item),
+        "-d", profileDir, "-f", pwfilePath, "-n", root, "-t", "CT,,"],
+        environment()).wait()
+    if ext == ".client":
+      Process(pk12util, ["-i", os.path.join(CERTS_DIR, item), "-w", pwfilePath,
+        "-d", profileDir], environment()).wait()
 
   os.unlink(pwfilePath)
   return 0
 
 def environment(env = None):
   if env == None:
     env = dict(os.environ)
 
@@ -439,16 +463,17 @@ def environment(env = None):
 
   return env
 
 ###############
 # RUN THE APP #
 ###############
 
 def runApp(testURL, env, app, profileDir, extraArgs):
+  "Run the app, returning a tuple containing the status code and the time at which it was started."
   if (IS_TEST_BUILD):
     # create certificate database for the profile
     certificateStatus = fillCertificateDB(profileDir)
     if certificateStatus != 0:
       log.info("ERROR FAIL Certificate integration")
       return certificateStatus
   
     # start ssltunnel to provide https:// URLs capability
@@ -485,9 +510,9 @@ def runApp(testURL, env, app, profileDir
   log.info("Application pid: %d", proc.pid)
   status = proc.wait()
   if status != 0:
     log.info("ERROR FAIL Exited with code %d during test run", status)
 
   if (IS_TEST_BUILD):
     ssltunnelProcess.kill()
   
-  return start
+  return (status, start)
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/LICENSE
@@ -0,0 +1,314 @@
+Blueprint CSS Framework License
+----------------------------------------------------------------
+
+Copyright (c) 2007-2008 Olav Bjorkoy (olav at bjorkoy.com)
+
+The Blueprint CSS Framework is available for use in all personal or 
+commercial projects, under both the (modified) MIT and the GPL license. You
+may choose the one that fits your project.
+
+
+The (modified) MIT License
+----------------------------------------------------------------
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice, and every other copyright notice found in this 
+software, and all the attributions in every file, and this permission notice 
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+The GPL License
+----------------------------------------------------------------
+
+        GNU GENERAL PUBLIC LICENSE
+           Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+          Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+        GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+          NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/Makefile.in
@@ -0,0 +1,63 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla PGO Input.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Robert Sayre <sayrer@gmail.com>
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_PROFILE_DIR = $(DEPTH)/_profile/pgo/blueprint
+
+_PGO_FILES = 	\
+  sample.html \
+  elements.html \
+  forms.html \
+  grid.html \
+  test.jpg \
+  test-small.jpg \
+  valid.png \
+  screen.css \
+  print.css \
+  grid.png \
+  fancytype-screen.css \
+  $(NULL)
+
+libs:: $(_PGO_FILES)
+	$(INSTALL) $^ $(_PROFILE_DIR)
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/elements.html
@@ -0,0 +1,246 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html lang="en">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+	<title>Blueprint HTML Elements Tests</title>
+
+  <!-- Framework CSS -->
+	<link rel="stylesheet" href="screen.css" type="text/css" media="screen, projection">
+	<link rel="stylesheet" href="print.css" type="text/css" media="print">
+  <!--[if IE]><link rel="stylesheet" href="ie.css" type="text/css" media="screen, projection"><![endif]-->
+
+</head>
+<body>
+
+	<div class="container showgrid">
+		<h2>Tests for common HTML elements</h2>
+		<hr>
+    
+    <h5>PARAGRAPHS <span class="alt">&amp;</span> BOXES</h5>
+    
+    <div class="span-8">    
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor <sub>sub text</sub> ut labore et <sup>sup text</sup> magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+    </div>
+    
+    <div class="span-8">
+			<p class="small">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+			<p class="large">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+    </div>
+    
+    <div class="span-8 last">
+
+			<div class="box">
+				<p class="last">Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+			</div>
+      <blockquote>
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+			</blockquote>    
+    
+    </div>
+    <hr>
+    
+    <h5>LISTS</h5>
+    
+    <div class="span-8">    
+			<ul>
+				<li>Unordered list test</li>
+				<li>Another list element. Lorem ipsum dolor sit amet, consectetur adipisicing elit.</li>
+				<li>Yet another element in the list</li>
+				<li>Some long text. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Lorem ipsum dolor sit amet, consectetur adipisicing elit.</li>
+			</ul>
+			<ol>
+				<li>Ordered list test</li>
+				<li>Another list element</li>
+				<li>Yet another element in the list</li>
+			</ol>
+    </div>
+    
+    <div class="span-8">
+			<ol>
+				<li>Ordered list</li>
+				<li>Here's a nested unordered list
+				  <ul>
+  				  <li>Nested Unordered list</li>
+  				  <li>Nested ordered list
+  				    <ol>
+  				      <li>The first</li>
+  				      <li>And the second</li>
+  				    </ol>
+  				  </li>
+  			  </ul>
+  			</li>
+				<li>Ordered List item</li>
+				<li>Nested Ordered list
+				  <ol>
+				    <li>Some point</li>
+				    <li>Nested Unordered list
+				      <ul>
+  				      <li>The first</li>
+  				      <li>And the second</li>
+				      </ul>
+				    </li>
+				  </ol>
+				</li>
+			</ol>
+    </div>
+    
+    <div class="span-8 last">
+      <dl>
+      	<dt>definition list dt</dt>
+      	<dd>definition list dd</dd>
+      	<dt>definition list dt</dt>
+      	<dd>definition list dd</dd>
+      	<dt>Lorem ipsum dolor sit amet, consectetur adipisicing elit adipisicing elit adipisicing elit</dt>
+      	<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit adipisicing elit adipisicing elit</dd>
+      	<dt>Lorem ipsum dolor sit amet, consectetur adipisicing elit adipisicing elit adipisicing elit</dt>
+      	<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit adipisicing elit adipisicing elit</dd>
+      </dl>			
+    </div>
+    <hr>
+    
+    <h5>HEADINGS</h5>
+    
+    <div class="span-8">    
+			<h1>H1: Lorem ipsum dolor sit amet</h1>
+			<h2>H2: Lorem ipsum dolor sit amet, consectetur elit</h2>
+			<h3>H3: Lorem ipsum dolor sit amet, consectetur adipisicing elit</h3>
+			<h4>H4: Lorem ipsum dolor sit amet, consectetur adipisicing elit adipis</h4>
+			<h5>H5: Lorem ipsum dolor sit amet, consectetur adipisicing elit adipisicing elit adipisicing elit</h5>
+			<h6>H6: Lorem ipsum dolor sit amet, consectetur adipisicing elit adipisicing elit adipisicing elit</h6>
+    </div>
+    
+    <div class="span-8">
+			<h1>Heading 1</h1><hr>
+			<h2>Heading 2</h2><hr>
+			<h3>Heading 3</h3><hr>
+			<h4>Heading 4</h4><hr>
+			<h5>Heading 5</h5><hr>
+			<h6>Heading 6</h6>
+    </div>
+    
+    <div class="span-8 last">
+			<h1>Heading 1</h1>
+			<h2>Heading 2</h2>
+			<h3>Heading 3</h3>
+			<h4>Heading 4</h4>
+			<h5>Heading 5</h5>
+			<h6>Heading 6</h6>
+    </div>
+    <hr>    
+    
+    <h5>MISC ELEMENTS</h5>
+    
+    <div class="span-8">    
+      <p>
+        <strong>&lt;strong&gt;</strong><br>
+        <del>&lt;del&gt; deleted</del><br>
+        <dfn>&lt;dfn&gt; dfn</dfn><br>
+        <em>&lt;em&gt; emphasis</em>
+      </p>
+      <p>
+        <a>&lt;a&gt; anchor</a><br>
+        <a href="http://www.google.com">&lt;a&gt; a + href</a>
+      </p>
+      <p>
+        <abbr title="extended abbr text should show when mouse over">&lt;abbr&gt; abbr - extended text when mouseover.</abbr><br>
+        <acronym title="extended acronym text should show when mouse over">&lt;acronym&gt; acronym - extended text when mouseover.</acronym>
+      </p>
+      <address>
+        &lt;address&gt;<br>
+        Donald Duck<br>
+        Box 555<br>
+        Disneyland
+      </address>
+      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore dolore.</p>
+    </div>
+    
+    <div class="span-8">
+      <table summary="This is the summary text for this table."  border="0" cellspacing="0" cellpadding="0">
+      	<caption><em>A standard test table with a caption, tr, td elements</em></caption>
+      	<tr>
+      		<th class="span-4">Table Header One</th>
+        	<th class="span-4 last">Table Header Two</th>
+      	</tr>
+      	<tr>
+      		<td>TD One</td>
+        	<td>TD Two</td>
+      	</tr>
+      	<tr>
+      		<td colspan="2">TD colspan 2</td>
+      	</tr>
+      </table>
+      
+      <table summary="This is the summary text for this table."  border="0" cellspacing="0" cellpadding="0">
+      	<caption><em>A test table with a thead, tfoot, and tbody elements</em></caption>
+      	<thead>
+      		<tr>
+      			<th class="span-4">Table Header One</th>
+      	  	<th class="span-4 last">Table Header Two</th>
+      		</tr>
+      	</thead>
+      	<tfoot>
+      		<tr>
+      			<td colspan="2">tfoot footer</td>
+      		</tr>
+      	</tfoot>
+      	<tbody>
+      		<tr>
+      			<td>TD One</td>
+      	  	<td>TD Two</td>
+      		</tr>
+      		<tr>
+      			<td>TD One</td>
+      	  	<td>TD Two</td>
+      		</tr>
+      	</tbody>
+      	<tbody>
+      		<tr>
+      			<td>TD One</td>
+      	  	<td>TD Two</td>
+      		</tr>
+      		<tr>
+      			<td>TD One</td>
+      	  	<td>TD Two</td>
+      		</tr>
+      	</tbody>
+      </table>
+    </div>
+    
+    <div class="span-8 last">
+
+<pre>&lt;pre&gt;
+pre  space1
+pre  space1
+pre    space2
+pre    space2
+pre	tab
+pre	tab</pre>
+
+<code>&lt;code&gt;
+Not indented
+	indent1
+	indent1
+		indent2
+			indent3</code>
+
+      <tt>&lt;tt&gt;
+      This tt text should be monospaced
+        and 
+        wrap as if 
+          one line of text
+            even though the code has newlines, spaces, and tabs. 
+      It should be the same size as &lt;p&gt; text.
+      </tt>
+    </div>
+    <hr>
+    
+    <p><a href="http://validator.w3.org/check?uri=referer">
+    <img src="valid.png" alt="Valid HTML 4.01 Strict" height="31" width="88" class="top"></a></p>
+		
+	</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/fancytype-screen.css
@@ -0,0 +1,71 @@
+/* -------------------------------------------------------------- 
+  
+   fancy-type.css
+   * Lots of pretty advanced classes for manipulating text.
+   
+   See the Readme file in this folder for additional instructions.
+
+-------------------------------------------------------------- */
+
+/* Indentation instead of line shifts for sibling paragraphs. */
+   p + p { text-indent:2em; margin-top:-1.5em; }
+   form p + p  { text-indent: 0; } /* Don't want this in forms. */
+   
+
+/* For great looking type, use this code instead of asdf: 
+   <span class="alt">asdf</span>  
+   Best used on prepositions and ampersands. */
+  
+.alt { 
+  color: #666; 
+  font-family: "Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua", Georgia, serif; 
+  font-style: italic;
+  font-weight: normal;
+}
+
+
+/* For great looking quote marks in titles, replace "asdf" with:
+   <span class="dquo">&#8220;</span>asdf&#8221;
+   (That is, when the title starts with a quote mark). 
+   (You may have to change this value depending on your font size). */  
+   
+.dquo { margin-left: -.5em; } 
+
+
+/* Reduced size type with incremental leading
+   (http://www.markboulton.co.uk/journal/comments/incremental_leading/)
+
+   This could be used for side notes. For smaller type, you don't necessarily want to 
+   follow the 1.5x vertical rhythm -- the line-height is too much. 
+   
+   Using this class, it reduces your font size and line-height so that for 
+   every four lines of normal sized type, there is five lines of the sidenote. eg:
+
+   New type size in em's:
+     10px (wanted side note size) / 12px (existing base size) = 0.8333 (new type size in ems)
+
+   New line-height value:
+     12px x 1.5 = 18px (old line-height)
+     18px x 4 = 72px 
+     72px / 5 = 14.4px (new line height)
+     14.4px / 10px = 1.44 (new line height in em's) */
+
+p.incr, .incr p {
+	font-size: 10px;
+	line-height: 1.44em;  
+	margin-bottom: 1.5em;
+}
+
+
+/* Surround uppercase words and abbreviations with this class.
+   Based on work by Jørgen Arnor Gårdsø Lom [http://twistedintellect.com/] */
+   
+.caps { 
+  font-variant: small-caps; 
+  letter-spacing: 1px; 
+  text-transform: lowercase; 
+  font-size:1.2em;
+  line-height:1%;
+  font-weight:bold;
+  padding:0 2px;
+}
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/forms.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html lang="en">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+	<title>Blueprint Forms Tests</title>
+
+  <!-- Framework CSS -->
+	<link rel="stylesheet" href="screen.css" type="text/css" media="screen, projection">
+	<link rel="stylesheet" href="print.css" type="text/css" media="print">
+  <!--[if IE]><link rel="stylesheet" href="ie.css" type="text/css" media="screen, projection"><![endif]-->
+</head>
+<body>
+
+	<div class="container showgrid">
+		<h1>Forms</h1>
+		<hr>
+    
+    <div class="span-12">
+    
+      <form id="dummy" action="" method="post">
+
+      	<fieldset>
+      		<legend>Simple sample form</legend>
+
+      		<p><label for="dummy0">Text input (title)</label><br>
+      		  <input type="text" class="title" name="dummy0" id="dummy0" value="Field with class .title"></p>
+        
+          <p><label for="dummy1">Another field</label><br>
+      		  <input type="text" class="text" id="dummy1" name="dummy1" value="Field with class .text"></p>
+
+      	  <p><label for="dummy2">Textarea</label><br>
+      	    <textarea name="dummy2" id="dummy2" rows="5" cols="20"></textarea></p>
+
+      		<p><input type="submit" value="Submit">
+      		  <input type="reset" value="Reset"></p>
+
+      	</fieldset>
+      </form>
+    
+    </div>
+    <div class="span-12 last">
+    
+      <div class="error">
+        This is a &lt;div&gt; with the class <strong>.error</strong>. <a href="#">Link</a>.
+      </div>
+      <div class="notice">
+        This is a &lt;div&gt; with the class <strong>.notice</strong>. <a href="#">Link</a>.
+      </div>		
+      <div class="success">
+        This is a &lt;div&gt; with the class <strong>.success</strong>. <a href="#">Link</a>.
+      </div>    
+      
+      <fieldset>
+        <legend>Select, checkboxes, lists</legend>
+
+    		<p><label for="dummy3">Select field</label><br>
+    		  <select id="dummy3" name="dummy3">
+    			  <option value="1">Ottawa</option>
+    			  <option value="2">Calgary</option>
+    			  <option value="3">Moosejaw</option>
+    		  </select></p>
+
+    		<p><label for="dummy4">Select with groups</label><br>
+    		  <select id="dummy4" name="dummy4">
+    			  <option>Favorite pet</option>
+    			  <optgroup label="mammals">
+    			    <option>dog</option>
+    			    <option>cat</option>
+    			    <option>rabbit</option>
+    			    <option>horse</option>
+    			  </optgroup>
+    			  <optgroup label="reptiles">
+    			    <option>iguana</option>
+    			    <option>snake</option>
+    			  </optgroup>
+    		  </select></p>
+    		  
+    		  <p><label>Radio buttons</label><br>
+    		    <input type="radio" name="example"> Radio one<br>
+    		    <input type="radio" name="example"> Radio two<br>
+    		    <input type="radio" name="example"> Radio three<br></p>
+          
+    		  <p><label>Checkboxes</label><br>
+    		    <input type="checkbox"> Check one<br>
+    		    <input type="checkbox"> Check two<br>
+    		    <input type="checkbox"> Check three<br></p>
+        
+      </fieldset>
+    
+    </div>
+    <hr>
+
+    <p><a href="http://validator.w3.org/check?uri=referer">
+    <img src="valid.png" alt="Valid HTML 4.01 Strict" height="31" width="88" class="top"></a></p>
+    
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/grid.html
@@ -0,0 +1,206 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html lang="en">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+	<title>Blueprint Grid Tests</title>
+
+  <!-- Framework CSS -->
+	<link rel="stylesheet" href="screen.css" type="text/css" media="screen, projection">
+	<link rel="stylesheet" href="print.css" type="text/css" media="print">
+  <!--[if IE]><link rel="stylesheet" href="ie.css" type="text/css" media="screen, projection"><![endif]-->
+</head>
+<body>
+
+	<div class="container showgrid">
+		<h1>Blueprint Tests: grid.css</h1>
+		
+
+		<div class="span-8">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<div class="span-8">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<div class="span-8 last">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		
+
+		<div class="span-6 append-1">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<div class="span-6 append-2">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<div class="span-6 append-3 last">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		
+
+		<div class="span-6 prepend-1">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<div class="span-6 prepend-2">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<div class="span-6 prepend-3 last">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
+		</div>
+		<hr>
+
+		<div class="span-12 border">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+		</div>
+		<div class="span-12 last">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+		</div>
+		<hr>
+
+		<div class="span-1 prepend-1"><p>1</p></div>
+		<div class="span-1 prepend-2"><p>2</p></div>
+		<div class="span-1 prepend-3"><p>3</p></div>
+		<div class="span-1 prepend-4"><p>4</p></div>
+		<div class="span-1 prepend-5"><p>5</p></div>
+		<div class="span-1 prepend-3 last"><p>3</p></div>
+
+		<div class="span-1 append-1"><p>1</p></div>
+		<div class="span-1 append-2"><p>2</p></div>
+		<div class="span-1 append-3"><p>3</p></div>
+		<div class="span-1 append-4"><p>4</p></div>
+		<div class="span-1 append-5"><p>5</p></div>
+		<div class="span-1 append-3 last"><p>3</p></div>
+		
+		<div class="span-1 border"><p>1</p></div>
+		<div class="span-1 border"><p>2</p></div>
+		<div class="span-1 border"><p>3</p></div>
+		<div class="span-1 border"><p>4</p></div>
+		<div class="span-1 border"><p>5</p></div>
+		<div class="span-1 border"><p>6</p></div>
+		<div class="span-1 border"><p>7</p></div>
+		<div class="span-1 border"><p>8</p></div>
+		<div class="span-1 border"><p>9</p></div>
+		<div class="span-1 border"><p>10</p></div>
+		<div class="span-1 border"><p>11</p></div>
+		<div class="span-1 border"><p>12</p></div>
+		<div class="span-1 border"><p>13</p></div>
+		<div class="span-1 border"><p>14</p></div>
+		<div class="span-1 border"><p>15</p></div>
+		<div class="span-1 border"><p>16</p></div>
+		<div class="span-1 border"><p>17</p></div>
+		<div class="span-1 border"><p>18</p></div>
+		<div class="span-1 border"><p>19</p></div>
+		<div class="span-1 border"><p>20</p></div>
+		<div class="span-1 border"><p>21</p></div>
+		<div class="span-1 border"><p>22</p></div>
+		<div class="span-1 border"><p>23</p></div>
+		<div class="span-1 last"><p>24</p></div>
+		
+		
+		<div class="span-4"><p>1</p></div>
+		<div class="span-4"><p>2</p></div>
+		<div class="span-4"><p>3</p></div>
+		<div class="span-4"><p>4</p></div>
+		<div class="span-4"><p>5</p></div>
+		<div class="span-4 last"><p>6</p></div>
+		
+		
+		<div class="prepend-23 span-1 last"><p>24</p></div>
+		
+		
+		<div class="prepend-1 span-1"><p>2</p></div>
+		<div class="prepend-20 span-1 append-1 last"><p>23</p></div>
+		<hr>
+		
+		<div class="span-24">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+		</div>
+		
+
+		<div class="span-12">
+			<div class="span-6">
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod.</p>
+			</div>
+
+			<div class="span-6 last">
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+			</div>
+
+			<div class="span-12 last">
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+			</div>
+		</div>
+
+		<div class="span-12 last">
+			<div class="span-6">
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod.</p>
+			</div>
+
+			<div class="span-6 last">
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+			</div>
+
+			<div class="span-12 last">
+				<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+			</div>
+		</div>
+		
+
+		<div class="span-14 prepend-5 append-5 last">
+			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+		</div>
+		<hr>
+		
+		<div class="span-12">
+		  <h5>TESTING .PUSH-1 TO .PUSH-5</h5>
+		
+			<div class="span-2"><img src="test-small.jpg" class="push-1"></div>
+			<div class="span-10 last"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+
+			<div class="span-2"><img src="test-small.jpg" class="push-2"></div>
+			<div class="span-10 last"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+		
+			<div class="span-2"><img src="test-small.jpg" class="push-3"></div>
+			<div class="span-10 last"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+
+			<div class="span-2"><img src="test-small.jpg" class="push-4"></div>
+			<div class="span-10 last"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+
+			<div class="span-2"><img src="test-small.jpg" class="push-5"></div>
+			<div class="span-10 last"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+		
+		</div>
+
+		<div class="span-12 last">
+		  <h5>TESTING .PULL-1 TO .PULL-5</h5>
+			
+			<div class="span-10"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+			<div class="span-2 last"><img src="test-small.jpg" class="top pull-1"></div>
+
+			<div class="span-10"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+			<div class="span-2 last"><img src="test-small.jpg" class="top pull-2"></div>		
+
+			<div class="span-10"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+			<div class="span-2 last"><img src="test-small.jpg" class="top pull-3"></div>		
+
+			<div class="span-10"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+			<div class="span-2 last"><img src="test-small.jpg" class="top pull-4"></div>		
+
+			<div class="span-10"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
+			<div class="span-2 last"><img src="test-small.jpg" class="top pull-5"></div>		
+
+		</div>
+		
+		
+		
+		
+		
+  	<div class="span-24">
+	    <p><a href="http://validator.w3.org/check?uri=referer">
+	    <img src="valid.png" alt="Valid HTML 4.01 Strict" height="31" width="88" class="bottom"></a></p>
+  	</div>		
+
+	</div>
+</body>
+</html>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..129d4a29fbe92688aabed5638e0c4f73a7bca818
GIT binary patch
literal 206
zc%17D@N?(olHy`uVBq!ia0vp^8bB<>!3HEX<>xE|QY^(zo*^7SP{WbZ0pxQQctjR6
zFmQbUVMeDlCNqG7G9|7NCBgY=CFO}lsSJ)O`AMk?Zka`?<@rU~#R|^B#xt(DF$2|k
zc)B=-cyuP$eEj#lzKxOL5tEL~%H%~Gtu@#d^DPnSv6>KM@XEpK;0k6<Ruq8+<qF)7
k*OxOVeOw)WWF<3$-)8pvpV!#E1DeU;>FVdQ&MBb@06Zo?vj6}9
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/print.css
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------
+
+   Blueprint CSS Framework 0.7.1
+   http://blueprintcss.googlecode.com
+
+   * Copyright (c) 2007-2008. See LICENSE for more info.
+   * See README for instructions on how to use Blueprint.
+   * For credits and origins, see AUTHORS.
+   * This is a compressed file. See the sources in the 'src' directory.
+
+----------------------------------------------------------------------- */
+
+/* print.css */
+body {line-height:1.5;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;color:#000;background:none;font-size:10pt;}
+.container {background:none;}
+hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
+hr.space {background:#fff;color:#fff;}
+h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
+code {font:.9em "Courier New", Monaco, Courier, monospace;}
+img {float:left;margin:1.5em 1.5em 1.5em 0;}
+a img {border:none;}
+p img.top {margin-top:0;}
+blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
+.small {font-size:.9em;}
+.large {font-size:1.1em;}
+.quiet {color:#999;}
+.hide {display:none;}
+a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
+a:link:after, a:visited:after {content:" (" attr(href) ") ";font-size:90%;}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/sample.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html lang="en">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+	<title>Blueprint Sample Page</title>
+
+  <!-- Framework CSS -->
+	<link rel="stylesheet" href="screen.css" type="text/css" media="screen, projection">
+	<link rel="stylesheet" href="print.css" type="text/css" media="print">
+  <!--[if IE]><link rel="stylesheet" href="ie.css" type="text/css" media="screen, projection"><![endif]-->
+	
+	<!-- Import fancy-type plugin for the sample page. -->
+	<link rel="stylesheet" href="fancytype-screen.css" type="text/css" media="screen, projection">
+</head>
+
+<body>
+
+	<div class="container">  
+		<h1>A simple sample page</h1>
+		<hr>
+		<h2 class="alt">This sample page demonstrates a tiny fraction of what you get with Blueprint.</h2>
+		<hr>
+		
+		<div class="span-7 colborder">
+		  <h6>Here's a box</h6>
+		  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.</p>
+		</div>
+
+		<div class="span-8 colborder">
+		  <h6>And another box</h6>
+		  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat laboris nisi ut aliquip.</p>
+		</div>
+		
+		<div class="span-7 last">
+		  <h6>This box is aligned with the sidebar</h6>
+		  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.</p>
+		</div>
+		<hr>
+		<hr class="space">
+
+		<div class="span-15 prepend-1 colborder">
+			<p><img src="test.jpg" class="top pull-1" alt="test">Lorem ipsum dolor sit amet, <em>consectetuer adipiscing elit</em>. Nunc congue ipsum vestibulum libero. Aenean vitae justo. Nam eget tellus. Etiam convallis, est eu lobortis mattis, lectus tellus tempus felis, a ultricies erat ipsum at metus.</p>
+			<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. <a href="#">Morbi et risus</a>. Aliquam nisl. Nulla facilisi. Cras accumsan vestibulum ante. Vestibulum sed tortor. Praesent <span class="caps">SMALL CAPS</span> tempus fringilla elit. Ut elit diam, sagittis in, nonummy in, gravida non, nunc. Ut orci. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nam egestas, orci eu imperdiet malesuada, nisl purus fringilla odio, quis commodo est orci vitae justo. Aliquam placerat odio tincidunt nulla. Cras in libero. Aenean rutrum, magna non tristique posuere, erat odio eleifend nisl, non convallis est tortor blandit ligula. Nulla id augue.</p>
+			<p>Nullam mattis, odio ut tempus facilisis, metus nisl facilisis metus, auctor consectetuer felis ligula nec mauris. Vestibulum odio erat, fermentum at, commodo vitae, ultrices et, urna. Mauris vulputate, mi pulvinar sagittis condimentum, sem nulla aliquam velit, sed imperdiet mi purus eu magna. Nulla varius metus ut eros. Aenean aliquet magna eget orci. Class aptent taciti sociosqu ad litora.</p>
+			<p>Vivamus euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse vel nibh ut turpis dictum sagittis. Aliquam vel velit a elit auctor sollicitudin. Nam vel dui vel neque lacinia pretium. Quisque nunc erat, venenatis id, volutpat ut, scelerisque sed, diam. Mauris ante. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec mattis. Morbi dignissim sollicitudin libero. Nulla lorem.</p>
+			<blockquote>
+				<p>Integer cursus ornare mauris. Praesent nisl arcu, imperdiet eu, ornare id, scelerisque ut, nunc. Praesent sagittis erat sed velit tempus imperdiet. Ut tristique, ante in interdum hendrerit, erat enim faucibus felis, quis rutrum mauris lorem quis sem. Vestibulum ligula nisi, mattis nec, posuere et, blandit eu, ligula. Nam suscipit placerat odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque tortor libero, venenatis vitae, rhoncus eu, placerat ut, mi. Nulla nulla.</p>
+			</blockquote>
+			<p>Maecenas vel metus quis magna pharetra fermentum. <em>Integer sit amet tortor</em>. Maecenas porttitor, pede sed gravida auctor, nulla augue aliquet elit, at pretium urna orci ut metus. Aliquam in dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, tellus id ornare posuere, quam nunc accumsan turpis, at convallis tellus orci et nisl. Phasellus congue neque a lorem.</p>
+			
+			<hr>
+			<div class="span-7 colborder">
+			  <h6>This is a nested column</h6>
+			  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
+			</div>
+			<div class="span-7 last">
+			  <h6>This is another nested column</h6>
+			  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
+			</div>
+			
+		</div>
+    <div class="span-7 last">
+			
+			<h3>A <span class="alt">Simple</span> Sidebar</h3>
+
+			<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ornare mattis nunc. Mauris venenatis, pede sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue.</p>
+			<p>Mauris a lectus. Aliquam erat volutpat. Phasellus ultrices mi a sapien. Nunc rutrum egestas lorem. Duis ac sem sagittis elit tincidunt gravida. Mauris a lectus. Aliquam erat volutpat. Phasellus ultrices mi a sapien. Nunc rutrum egestas lorem. Duis ac sem sagittis elit tincidunt gravida.</p>
+			<p class="quiet">Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ornare mattis nunc. Mauris venenatis, pede sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue.</p>
+
+			<h5>Incremental leading</h5>
+			<p class="incr">Vestibulum ante ipsum primis in faucibus orci luctus vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ornare mattis nunc. Mauris venenatis, pede sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue. sed aliquet vehicula, lectus tellus.</p>
+			<p class="incr">Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ornare mattis nunc. Mauris venenatis, pede sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue. sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue. ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras ornare mattis nunc. Mauris venenatis, pede sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue. sed aliquet vehicula, lectus tellus pulvinar neque, non cursus sem nisi vel augue.</p>
+		
+		</div>
+		
+		<hr>
+		<h2 class="alt">You may pick and choose amongst these and many more features, so be bold.</h2>
+		<hr>
+
+    <p><a href="http://validator.w3.org/check?uri=referer">
+    <img src="valid.png" alt="Valid HTML 4.01 Strict" height="31" width="88" class="top"></a></p>
+	</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/blueprint/screen.css
@@ -0,0 +1,226 @@
+/* -----------------------------------------------------------------------
+
+   Blueprint CSS Framework 0.7.1
+   http://blueprintcss.googlecode.com
+
+   * Copyright (c) 2007-2008. See LICENSE for more info.
+   * See README for instructions on how to use Blueprint.
+   * For credits and origins, see AUTHORS.
+   * This is a compressed file. See the sources in the 'src' directory.
+
+----------------------------------------------------------------------- */
+
+/* reset.css */
+html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
+body {line-height:1.5;}
+table {border-collapse:separate;border-spacing:0;}
+caption, th, td {text-align:left;font-weight:normal;}
+table, td, th {vertical-align:middle;}
+blockquote:before, blockquote:after, q:before, q:after {content:"";}
+blockquote, q {quotes:"" "";}
+a img {border:none;}
+
+/* typography.css */
+body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;}
+h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
+h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
+h2 {font-size:2em;margin-bottom:0.75em;}
+h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
+h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;height:1.25em;}
+h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
+h6 {font-size:1em;font-weight:bold;}
+h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
+p {margin:0 0 1.5em;}
+p img {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
+p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
+a:focus, a:hover {color:#000;}
+a {color:#009;text-decoration:underline;}
+blockquote {margin:1.5em;color:#666;font-style:italic;}
+strong {font-weight:bold;}
+em, dfn {font-style:italic;}
+dfn {font-weight:bold;}
+sup, sub {line-height:0;}
+abbr, acronym {border-bottom:1px dotted #666;}
+address {margin:0 0 1.5em;font-style:italic;}
+del {color:#666;}
+pre, code {margin:1.5em 0;white-space:pre;}
+pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
+li ul, li ol {margin:0 1.5em;}
+ul, ol {margin:0 1.5em 1.5em 1.5em;}
+ul {list-style-type:disc;}
+ol {list-style-type:decimal;}
+dl {margin:0 0 1.5em 0;}
+dl dt {font-weight:bold;}
+dd {margin-left:1.5em;}
+table {margin-bottom:1.4em;width:100%;}
+th {font-weight:bold;background:#C3D9FF;}
+th, td {padding:4px 10px 4px 5px;}
+tr.even td {background:#E5ECF9;}
+tfoot {font-style:italic;}
+caption {background:#eee;}
+.small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
+.large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
+.hide {display:none;}
+.quiet {color:#666;}
+.loud {color:#000;}
+.highlight {background:#ff0;}
+.added {background:#060;color:#fff;}
+.removed {background:#900;color:#fff;}
+.first {margin-left:0;padding-left:0;}
+.last {margin-right:0;padding-right:0;}
+.top {margin-top:0;padding-top:0;}
+.bottom {margin-bottom:0;padding-bottom:0;}
+
+/* grid.css */
+.container {width:950px;margin:0 auto;}
+.showgrid {background:url(grid.png);}
+body {margin:1.5em 0;}
+div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12, div.span-13, div.span-14, div.span-15, div.span-16, div.span-17, div.span-18, div.span-19, div.span-20, div.span-21, div.span-22, div.span-23, div.span-24 {float:left;margin-right:10px;}
+div.last {margin-right:0;}
+.span-1 {width:30px;}
+.span-2 {width:70px;}
+.span-3 {width:110px;}
+.span-4 {width:150px;}
+.span-5 {width:190px;}
+.span-6 {width:230px;}
+.span-7 {width:270px;}
+.span-8 {width:310px;}
+.span-9 {width:350px;}
+.span-10 {width:390px;}
+.span-11 {width:430px;}
+.span-12 {width:470px;}
+.span-13 {width:510px;}
+.span-14 {width:550px;}
+.span-15 {width:590px;}
+.span-16 {width:630px;}
+.span-17 {width:670px;}
+.span-18 {width:710px;}
+.span-19 {width:750px;}
+.span-20 {width:790px;}
+.span-21 {width:830px;}
+.span-22 {width:870px;}
+.span-23 {width:910px;}
+.span-24, div.span-24 {width:950px;margin:0;}
+.append-1 {padding-right:40px;}
+.append-2 {padding-right:80px;}
+.append-3 {padding-right:120px;}
+.append-4 {padding-right:160px;}
+.append-5 {padding-right:200px;}
+.append-6 {padding-right:240px;}
+.append-7 {padding-right:280px;}
+.append-8 {padding-right:320px;}
+.append-9 {padding-right:360px;}
+.append-10 {padding-right:400px;}
+.append-11 {padding-right:440px;}
+.append-12 {padding-right:480px;}
+.append-13 {padding-right:520px;}
+.append-14 {padding-right:560px;}
+.append-15 {padding-right:600px;}
+.append-16 {padding-right:640px;}
+.append-17 {padding-right:680px;}
+.append-18 {padding-right:720px;}
+.append-19 {padding-right:760px;}
+.append-20 {padding-right:800px;}
+.append-21 {padding-right:840px;}
+.append-22 {padding-right:880px;}
+.append-23 {padding-right:920px;}
+.prepend-1 {padding-left:40px;}
+.prepend-2 {padding-left:80px;}
+.prepend-3 {padding-left:120px;}
+.prepend-4 {padding-left:160px;}
+.prepend-5 {padding-left:200px;}
+.prepend-6 {padding-left:240px;}
+.prepend-7 {padding-left:280px;}
+.prepend-8 {padding-left:320px;}
+.prepend-9 {padding-left:360px;}
+.prepend-10 {padding-left:400px;}
+.prepend-11 {padding-left:440px;}
+.prepend-12 {padding-left:480px;}
+.prepend-13 {padding-left:520px;}
+.prepend-14 {padding-left:560px;}
+.prepend-15 {padding-left:600px;}
+.prepend-16 {padding-left:640px;}
+.prepend-17 {padding-left:680px;}
+.prepend-18 {padding-left:720px;}
+.prepend-19 {padding-left:760px;}
+.prepend-20 {padding-left:800px;}
+.prepend-21 {padding-left:840px;}
+.prepend-22 {padding-left:880px;}
+.prepend-23 {padding-left:920px;}
+div.border {padding-right:4px;margin-right:5px;border-right:1px solid #eee;}
+div.colborder {padding-right:24px;margin-right:25px;border-right:1px solid #eee;}
+.pull-1 {margin-left:-40px;}
+.pull-2 {margin-left:-80px;}
+.pull-3 {margin-left:-120px;}
+.pull-4 {margin-left:-160px;}
+.pull-5 {margin-left:-200px;}
+.pull-6 {margin-left:-240px;}
+.pull-7 {margin-left:-280px;}
+.pull-8 {margin-left:-320px;}
+.pull-9 {margin-left:-360px;}
+.pull-10 {margin-left:-400px;}
+.pull-11 {margin-left:-440px;}
+.pull-12 {margin-left:-480px;}
+.pull-13 {margin-left:-520px;}
+.pull-14 {margin-left:-560px;}
+.pull-15 {margin-left:-600px;}
+.pull-16 {margin-left:-640px;}
+.pull-17 {margin-left:-680px;}
+.pull-18 {margin-left:-720px;}
+.pull-19 {margin-left:-760px;}
+.pull-20 {margin-left:-800px;}
+.pull-21 {margin-left:-840px;}
+.pull-22 {margin-left:-880px;}
+.pull-23 {margin-left:-920px;}
+.pull-24 {margin-left:-960px;}
+.pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;}
+.push-1 {margin:0 -40px 1.5em 40px;}
+.push-2 {margin:0 -80px 1.5em 80px;}
+.push-3 {margin:0 -120px 1.5em 120px;}
+.push-4 {margin:0 -160px 1.5em 160px;}
+.push-5 {margin:0 -200px 1.5em 200px;}
+.push-6 {margin:0 -240px 1.5em 240px;}
+.push-7 {margin:0 -280px 1.5em 280px;}
+.push-8 {margin:0 -320px 1.5em 320px;}
+.push-9 {margin:0 -360px 1.5em 360px;}
+.push-10 {margin:0 -400px 1.5em 400px;}
+.push-11 {margin:0 -440px 1.5em 440px;}
+.push-12 {margin:0 -480px 1.5em 480px;}
+.push-13 {margin:0 -520px 1.5em 520px;}
+.push-14 {margin:0 -560px 1.5em 560px;}
+.push-15 {margin:0 -600px 1.5em 600px;}
+.push-16 {margin:0 -640px 1.5em 640px;}
+.push-17 {margin:0 -680px 1.5em 680px;}
+.push-18 {margin:0 -720px 1.5em 720px;}
+.push-19 {margin:0 -760px 1.5em 760px;}
+.push-20 {margin:0 -800px 1.5em 800px;}
+.push-21 {margin:0 -840px 1.5em 840px;}
+.push-22 {margin:0 -880px 1.5em 880px;}
+.push-23 {margin:0 -920px 1.5em 920px;}
+.push-24 {margin:0 -960px 1.5em 960px;}
+.push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:right;position:relative;}
+.box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
+hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;}
+hr.space {background:#fff;color:#fff;}
+.clearfix:after, .container:after {content:".";display:block;height:0;clear:both;visibility:hidden;}
+.clearfix, .container {display:inline-block;}
+* html .clearfix, * html .container {height:1%;}
+.clearfix, .container {display:block;}
+.clear {clear:both;}
+
+/* forms.css */
+label {font-weight:bold;}
+fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
+legend {font-weight:bold;font-size:1.2em;}
+input.text, input.title, textarea, select {margin:0.5em 0;border:1px solid #bbb;}
+input.text:focus, input.title:focus, textarea:focus, select:focus {border:1px solid #666;}
+input.text, input.title {width:300px;padding:5px;}
+input.title {font-size:1.5em;}
+textarea {width:390px;height:250px;padding:5px;}
+.error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;}
+.error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;}
+.notice {background:#FFF6BF;color:#514721;border-color:#FFD324;}
+.success {background:#E6EFC2;color:#264409;border-color:#C6D880;}
+.error a {color:#8a1f11;}
+.notice a {color:#514721;}
+.success a {color:#264409;}
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..aa599d99a94cd487a44ad9bf7e2388d45e863238
GIT binary patch
literal 1886
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
L;7$rx58wO=Zj&W}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0107be27349330250c3c28f52ef5dd58a25690ce
GIT binary patch
literal 35467
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%0A{TF@fekGH3(xe%KOACB23
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
Ye*KWg-KW?D{rG{>-ZERXHXjTB*=x0UEdT%j
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dd20e497e37a97a6ee56d666a0b6d502bf9176d0
GIT binary patch
literal 1669
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
--- a/build/pgo/certs/Makefile.in
+++ b/build/pgo/certs/Makefile.in
@@ -41,24 +41,34 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 _PROFILE_DIR = $(DEPTH)/_profile/pgo
 _CERTS_DIR = $(_PROFILE_DIR)/certs
 
-# Extension of files must be '.ca'
+# Following files will be added as trusted Certificate Authorities
+# to the PGO profile.
+# Extension of those files MUST BE '.ca'.
 _CERT_AUTHORITIES = \
     pgoca.ca \
     $(NULL)
 
+
+# Following files will be added as user/client certificates
+# to the PGO profile to be used for client authentication.
+# Extension of those files MUST BE '.client'.
+_CLIENT_CERTS = \
+    mochitest.client \
+    $(NULL)
+
 _SERV_FILES = \
     pgoca.p12 \
     cert8.db \
     key3.db \
     secmod.db \
     $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
-libs:: $(_SERV_FILES) $(_CERT_AUTHORITIES)
+libs:: $(_SERV_FILES) $(_CERT_AUTHORITIES) $(_CLIENT_CERTS)
 	$(INSTALL) $^ $(_CERTS_DIR)
index f932a32b5558d5882fb80c6063b0ee06492e7ee9..96486df5f6a84adddb45fbf3ef6fc770f2b54137
GIT binary patch
literal 65536
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
k00000000000000000000000000000000000002DtFPaqk(*OVf
index be32cd6bf0ba25e2c2896e045f499d7213100069..da98cabe9507b38c08e761dd66b1ccdb3892b4b5
GIT binary patch
literal 45056
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5d72cd2b739b3127724e12d63c0c7e79c62666ed
GIT binary patch
literal 2388
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
Qt|>;}`B>A+U<v^62lsS9EdT%j
copy from modules/libpr0n/test/unit/image3.ico
copy to build/pgo/favicon.ico
--- a/build/pgo/index.html
+++ b/build/pgo/index.html
@@ -1,14 +1,208 @@
-<html>
-<head>
-<title>PGO</title>
-<script src="quit.js"></script>
-</head>
-<body>
-
-Just going to quit after a timeout for now...
-
 <script>
-setTimeout(goQuitApplication, 10000);
-</script>
-</body>
-</html>
+ /* ***** BEGIN LICENSE BLOCK *****
+  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+  *
+  * The contents of this file are subject to the Mozilla Public License Version
+  * 1.1 (the "License"); you may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at
+  * http://www.mozilla.org/MPL/
+  *
+  * Software distributed under the License is distributed on an "AS IS" basis,
+  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+  * for the specific language governing rights and limitations under the
+  * License.
+  *
+  * The Original Code is Mozilla Automated Testing Code.
+  *
+  * The Initial Developer of the Original Code is
+  * Mozilla Corporation.
+  * Portions created by the Initial Developer are Copyright (C) 2005
+  * the Initial Developer. All Rights Reserved.
+  *
+  * Contributor(s):
+  *   Bob Clary <bob@bclary.com>
+  *   Jeff Walden <jwalden+code@mit.edu>
+  *
+  * Alternatively, the contents of this file may be used under the terms of
+  * either the GNU General Public License Version 2 or later (the "GPL"), or
+  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+  * in which case the provisions of the GPL or the LGPL are applicable instead
+  * of those above. If you wish to allow use of your version of this file only
+  * under the terms of either the GPL or the LGPL, and not to allow others to
+  * use your version of this file under the terms of the MPL, indicate your
+  * decision by deleting the provisions above and replace them with the notice
+  * and other provisions required by the GPL or the LGPL. If you do not delete
+  * the provisions above, a recipient may use your version of this file under
+  * the terms of any one of the MPL, the GPL or the LGPL.
+  *
+  * ***** END LICENSE BLOCK ***** */
+  
+ function quitHook()
+ {
+   var xhr = new XMLHttpRequest();
+   xhr.open("GET", "http://" + location.host + "/server/shutdown", true);
+   xhr.onreadystatechange = function (event)
+     {
+       if (xhr.readyState == 4)
+         goQuitApplication();
+     };
+   xhr.send(null);
+ }
+  
+ function canQuitApplication()
+ {
+   var os = Components.classes["@mozilla.org/observer-service;1"]
+     .getService(Components.interfaces.nsIObserverService);
+   if (!os) 
+   {
+     return true;
+   }
+   
+   try 
+   {
+     var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
+       .createInstance(Components.interfaces.nsISupportsPRBool);
+     os.notifyObservers(cancelQuit, "quit-application-requested", null);
+     
+     // Something aborted the quit process. 
+     if (cancelQuit.data)
+     {
+       return false;
+     }
+   }
+   catch (ex) 
+   {
+   }
+   os.notifyObservers(null, "quit-application-granted", null);
+   return true;
+ }
+ 
+ function goQuitApplication()
+ {
+   const privs = 'UniversalXPConnect';
+ 
+   try
+   {
+     netscape.security.PrivilegeManager.enablePrivilege(privs);
+   }
+   catch(ex)
+   {
+     throw('goQuitApplication: privilege failure ' + ex);
+   }
+ 
+   if (!canQuitApplication())
+   {
+     return false;
+   }
+ 
+   const kAppStartup = '@mozilla.org/toolkit/app-startup;1';
+   const kAppShell   = '@mozilla.org/appshell/appShellService;1';
+   var   appService;
+   var   forceQuit;
+ 
+   if (kAppStartup in Components.classes)
+   {
+     appService = Components.classes[kAppStartup].
+       getService(Components.interfaces.nsIAppStartup);
+     forceQuit  = Components.interfaces.nsIAppStartup.eForceQuit;
+ 
+   }
+   else if (kAppShell in Components.classes)
+   {
+     appService = Components.classes[kAppShell].
+       getService(Components.interfaces.nsIAppShellService);
+     forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
+   }
+   else
+   {
+     throw 'goQuitApplication: no AppStartup/appShell';
+   }
+ 
+   var windowManager = Components.
+     classes['@mozilla.org/appshell/window-mediator;1'].getService();
+ 
+   var windowManagerInterface = windowManager.
+     QueryInterface(Components.interfaces.nsIWindowMediator);
+ 
+   var enumerator = windowManagerInterface.getEnumerator(null);
+ 
+   while (enumerator.hasMoreElements())
+   {
+     var domWindow = enumerator.getNext();
+     if (("tryToClose" in domWindow) && !domWindow.tryToClose())
+     {
+       return false;
+     }
+     domWindow.close();
+   }
+ 
+   try
+   {
+     appService.quit(forceQuit);
+   }
+   catch(ex)
+   {
+     throw('goQuitApplication: ' + ex);
+   }
+ 
+   return true;
+ }
+ 
+ var list = 
+     [
+  "blueprint/sample.html",
+  "blueprint/forms.html",
+  "blueprint/grid.html",
+  "blueprint/elements.html",
+  "js-input/3d-cube.html",
+  "js-input/3d-morph.html",
+  "js-input/3d-raytrace.html",
+  "js-input/3d-thingy.html",
+  "js-input/access-binary-trees.html",
+  "js-input/access-fannkuch.html",
+  "js-input/access-nbody.html",
+  "js-input/access-nsieve.html",
+  "js-input/bitops-3bit-bits-in-byte.html",
+  "js-input/bitops-bits-in-byte.html",
+  "js-input/bitops-bitwise-and.html",
+  "js-input/bitops-nsieve-bits.html",
+  "js-input/controlflow-recursive.html",
+  "js-input/crypto-aes.html",
+  "js-input/crypto-md5.html",
+  "js-input/crypto-sha1.html",
+  "js-input/crypto-otp.html",
+  "js-input/date-format-tofte.html",
+  "js-input/date-format-xparb.html",
+  "js-input/math-cordic.html",
+  "js-input/math-partial-sums.html",
+  "js-input/math-spectral-norm.html",
+  "js-input/regexp-dna.html",
+  "js-input/string-base64.html",
+  "js-input/string-fasta.html",
+  "js-input/string-tagcloud.html",
+  "js-input/string-unpack-code.html",
+  "js-input/string-validate-input.html"
+     ];
+ var interval = 3000; // 15000
+ var idx = 0;
+ var w;
+ 
+ window.onload = function () {
+     w = window.open("about:blank");
+     window.setTimeout(loadURL, interval); 
+ };
+ function loadURL () {
+     w.location.href = list[idx++];
+     if (idx < list.length) {
+ 	window.setTimeout(loadURL, interval);
+     } else {
+         window.setTimeout(goQuitApplication, interval);
+     }
+ }
+ var i;
+ 
+ for(i=0; i < list.length;i++) {
+     document.write(list[i]);
+     document.write("<br>");
+ }
+  </script>
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/3d-cube.html
@@ -0,0 +1,387 @@
+<!DOCTYPE html>
+<head>
+<!--
+ Copyright (C) 2007 Apple Inc.  All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+-->
+
+<title>SunSpider 3d-cube</title>
+
+</head>
+
+<body>
+<h3>3d-cube</h3>
+<div id="console">
+</div>
+
+<script>
+
+var _sunSpiderStartDate = new Date();
+
+// 3D Cube Rotation
+// http://www.speich.net/computer/moztesting/3d.htm
+// Created by Simon Speich
+
+var Q = new Array();
+var MTrans = new Array();  // transformation matrix
+var MQube = new Array();  // position information of qube
+var I = new Array();      // entity matrix
+var Origin = new Object();
+var Testing = new Object();
+var LoopTimer;
+
+var DisplArea = new Object();
+DisplArea.Width = 300;
+DisplArea.Height = 300;
+
+function DrawLine(From, To) {
+  var x1 = From.V[0];
+  var x2 = To.V[0];
+  var y1 = From.V[1];
+  var y2 = To.V[1];
+  var dx = Math.abs(x2 - x1);
+  var dy = Math.abs(y2 - y1);
+  var x = x1;
+  var y = y1;
+  var IncX1, IncY1;
+  var IncX2, IncY2;  
+  var Den;
+  var Num;
+  var NumAdd;
+  var NumPix;
+
+  if (x2 >= x1) {  IncX1 = 1; IncX2 = 1;  }
+  else { IncX1 = -1; IncX2 = -1; }
+  if (y2 >= y1)  {  IncY1 = 1; IncY2 = 1; }
+  else { IncY1 = -1; IncY2 = -1; }
+  if (dx >= dy) {
+    IncX1 = 0;
+    IncY2 = 0;
+    Den = dx;
+    Num = dx / 2;
+    NumAdd = dy;
+    NumPix = dx;
+  }
+  else {
+    IncX2 = 0;
+    IncY1 = 0;
+    Den = dy;
+    Num = dy / 2;
+    NumAdd = dx;
+    NumPix = dy;
+  }
+
+  NumPix = Math.round(Q.LastPx + NumPix);
+
+  var i = Q.LastPx;
+  for (; i < NumPix; i++) {
+    Num += NumAdd;
+    if (Num >= Den) {
+      Num -= Den;
+      x += IncX1;
+      y += IncY1;
+    }
+    x += IncX2;
+    y += IncY2;
+  }
+  Q.LastPx = NumPix;
+}
+
+function CalcCross(V0, V1) {
+  var Cross = new Array();
+  Cross[0] = V0[1]*V1[2] - V0[2]*V1[1];
+  Cross[1] = V0[2]*V1[0] - V0[0]*V1[2];
+  Cross[2] = V0[0]*V1[1] - V0[1]*V1[0];
+  return Cross;
+}
+
+function CalcNormal(V0, V1, V2) {
+  var A = new Array();   var B = new Array(); 
+  for (var i = 0; i < 3; i++) {
+    A[i] = V0[i] - V1[i];
+    B[i] = V2[i] - V1[i];
+  }
+  A = CalcCross(A, B);
+  var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); 
+  for (var i = 0; i < 3; i++) A[i] = A[i] / Length;
+  A[3] = 1;
+  return A;
+}
+
+function CreateP(X,Y,Z) {
+  this.V = [X,Y,Z,1];
+}
+
+// multiplies two matrices
+function MMulti(M1, M2) {
+  var M = [[],[],[],[]];
+  var i = 0;
+  var j = 0;
+  for (; i < 4; i++) {
+    j = 0;
+    for (; j < 4; j++) M[i][j] = M1[i][0] * M2[0][j] + M1[i][1] * M2[1][j] + M1[i][2] * M2[2][j] + M1[i][3] * M2[3][j];
+  }
+  return M;
+}
+
+//multiplies matrix with vector
+function VMulti(M, V) {
+  var Vect = new Array();
+  var i = 0;
+  for (;i < 4; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2] + M[i][3] * V[3];
+  return Vect;
+}
+
+function VMulti2(M, V) {
+  var Vect = new Array();
+  var i = 0;
+  for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2];
+  return Vect;
+}
+
+// add to matrices
+function MAdd(M1, M2) {
+  var M = [[],[],[],[]];
+  var i = 0;
+  var j = 0;
+  for (; i < 4; i++) {
+    j = 0;
+    for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j];
+  }
+  return M;
+}
+
+function Translate(M, Dx, Dy, Dz) {
+  var T = [
+  [1,0,0,Dx],
+  [0,1,0,Dy],
+  [0,0,1,Dz],
+  [0,0,0,1]
+  ];
+  return MMulti(T, M);
+}
+
+function RotateX(M, Phi) {
+  var a = Phi;
+  a *= Math.PI / 180;
+  var Cos = Math.cos(a);
+  var Sin = Math.sin(a);
+  var R = [
+  [1,0,0,0],
+  [0,Cos,-Sin,0],
+  [0,Sin,Cos,0],
+  [0,0,0,1]
+  ];
+  return MMulti(R, M);
+}
+
+function RotateY(M, Phi) {
+  var a = Phi;
+  a *= Math.PI / 180;
+  var Cos = Math.cos(a);
+  var Sin = Math.sin(a);
+  var R = [
+  [Cos,0,Sin,0],
+  [0,1,0,0],
+  [-Sin,0,Cos,0],
+  [0,0,0,1]
+  ];
+  return MMulti(R, M);
+}
+
+function RotateZ(M, Phi) {
+  var a = Phi;
+  a *= Math.PI / 180;
+  var Cos = Math.cos(a);
+  var Sin = Math.sin(a);
+  var R = [
+  [Cos,-Sin,0,0],
+  [Sin,Cos,0,0],
+  [0,0,1,0],   
+  [0,0,0,1]
+  ];
+  return MMulti(R, M);
+}
+
+function DrawQube() {
+  // calc current normals
+  var CurN = new Array();
+  var i = 5;
+  Q.LastPx = 0;
+  for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]);
+  if (CurN[0][2] < 0) {
+    if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; };
+    if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; };
+    if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; };
+    if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; };
+  }
+  if (CurN[1][2] < 0) {
+    if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; };
+    if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; };
+    if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
+    if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; };
+  }
+  if (CurN[2][2] < 0) {
+    if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
+    if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
+    if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
+    if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
+  }
+  if (CurN[3][2] < 0) {
+    if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
+    if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; };
+    if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; };
+    if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; };
+  }
+  if (CurN[4][2] < 0) {
+    if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; };
+    if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; };
+    if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; };
+    if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
+  }
+  if (CurN[5][2] < 0) {
+    if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; };
+    if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
+    if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; };
+    if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; };
+  }
+  Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
+  Q.LastPx = 0;
+}
+
+function Loop() {
+  if (Testing.LoopCount > Testing.LoopMax) return;
+  var TestingStr = String(Testing.LoopCount);
+  while (TestingStr.length < 3) TestingStr = "0" + TestingStr;
+  MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]);
+  MTrans = RotateX(MTrans, 1);
+  MTrans = RotateY(MTrans, 3);
+  MTrans = RotateZ(MTrans, 5);
+  MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]);
+  MQube = MMulti(MTrans, MQube);
+  var i = 8;
+  for (; i > -1; i--) {
+    Q[i].V = VMulti(MTrans, Q[i].V);
+  }
+  DrawQube();
+  Testing.LoopCount++;
+  Loop();
+}
+
+function Init(CubeSize) {
+  // init/reset vars
+  Origin.V = [150,150,20,1];
+  Testing.LoopCount = 0;
+  Testing.LoopMax = 50;
+  Testing.TimeMax = 0;
+  Testing.TimeAvg = 0;
+  Testing.TimeMin = 0;
+  Testing.TimeTemp = 0;
+  Testing.TimeTotal = 0;
+  Testing.Init = false;
+
+  // transformation matrix
+  MTrans = [
+  [1,0,0,0],
+  [0,1,0,0],
+  [0,0,1,0],
+  [0,0,0,1]
+  ];
+  
+  // position information of qube
+  MQube = [
+  [1,0,0,0],
+  [0,1,0,0],
+  [0,0,1,0],
+  [0,0,0,1]
+  ];
+  
+  // entity matrix
+  I = [
+  [1,0,0,0],
+  [0,1,0,0],
+  [0,0,1,0],
+  [0,0,0,1]
+  ];
+  
+  // create qube
+  Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize);
+  Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize);
+  Q[2] = new CreateP( CubeSize, CubeSize, CubeSize);
+  Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize);
+  Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize);
+  Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize);
+  Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize);
+  Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize);
+  
+  // center of gravity
+  Q[8] = new CreateP(0, 0, 0);
+  
+  // anti-clockwise edge check
+  Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]];
+  
+  // calculate squad normals
+  Q.Normal = new Array();
+  for (var i = 0; i < Q.Edge.length; i++) Q.Normal[i] = CalcNormal(Q[Q.Edge[i][0]].V, Q[Q.Edge[i][1]].V, Q[Q.Edge[i][2]].V);
+  
+  // line drawn ?
+  Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
+  
+  // create line pixels
+  Q.NumPx = 9 * 2 * CubeSize;
+  for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0);
+  
+  MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]);
+  MQube = MMulti(MTrans, MQube);
+
+  var i = 0;
+  for (; i < 9; i++) {
+    Q[i].V = VMulti(MTrans, Q[i].V);
+  }
+  DrawQube();
+  Testing.Init = true;
+  Loop();
+}
+
+for ( var i = 20; i <= 160; i *= 2 ) {
+  Init(i);
+}
+
+Q = null;
+MTrans = null;
+MQube = null;
+I = null;
+Origin = null;
+Testing = null;
+LoopTime = null;
+DisplArea = null;
+
+
+var _sunSpiderInterval = new Date() - _sunSpiderStartDate;
+
+document.getElementById("console").innerHTML = _sunSpiderInterval;
+</script>
+
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/3d-morph.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<head>
+<!--
+ Copyright (C) 2007 Apple Inc.  All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+-->
+
+<title>SunSpider 3d-morph</title>
+
+</head>
+
+<body>
+<h3>3d-morph</h3>
+<div id="console">
+</div>
+
+<script>
+
+var _sunSpiderStartDate = new Date();
+
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+var loops = 15
+var nx = 120
+var nz = 120
+
+function morph(a, f) {
+    var PI2nx = Math.PI * 8/nx
+    var sin = Math.sin
+    var f30 = -(50 * sin(f*Math.PI*2))
+    
+    for (var i = 0; i < nz; ++i) {
+        for (var j = 0; j < nx; ++j) {
+            a[3*(i*nx+j)+1]    = sin((j-1) * PI2nx ) * -f30
+        }
+    }
+}
+
+    
+var a = Array()
+for (var i=0; i < nx*nz*3; ++i) 
+    a[i] = 0
+
+for (var i = 0; i < loops; ++i) {
+    morph(a, i/loops)
+}
+
+testOutput = 0;
+for (var i = 0; i < nx; i++)
+    testOutput += a[3*(i*nx+i)+1];
+a = null;
+
+
+var _sunSpiderInterval = new Date() - _sunSpiderStartDate;
+
+document.getElementById("console").innerHTML = _sunSpiderInterval;
+</script>
+
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/3d-raytrace.html
@@ -0,0 +1,490 @@
+<!DOCTYPE html>
+<head>
+<!--
+ Copyright (C) 2007 Apple Inc.  All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+-->
+
+<title>SunSpider 3d-raytrace</title>
+</head>
+
+<body>
+<h3>3d-raytrace</h3>
+<div id="console">
+</div>
+
+<script>
+
+var _sunSpiderStartDate = new Date();
+
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+function createVector(x,y,z) {
+    return new Array(x,y,z);
+}
+
+function sqrLengthVector(self) {
+    return self[0] * self[0] + self[1] * self[1] + self[2] * self[2];
+}
+
+function lengthVector(self) {
+    return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
+}
+
+function addVector(self, v) {
+    self[0] += v[0];
+    self[1] += v[1];
+    self[2] += v[2];
+    return self;
+}
+
+function subVector(self, v) {
+    self[0] -= v[0];
+    self[1] -= v[1];
+    self[2] -= v[2];
+    return self;
+}
+
+function scaleVector(self, scale) {
+    self[0] *= scale;
+    self[1] *= scale;
+    self[2] *= scale;
+    return self;
+}
+
+function normaliseVector(self) {
+    var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
+    self[0] /= len;
+    self[1] /= len;
+    self[2] /= len;
+    return self;
+}
+
+function add(v1, v2) {
+    return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
+}
+
+function sub(v1, v2) {
+    return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
+}
+
+function scalev(v1, v2) {
+    return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);
+}
+
+function dot(v1, v2) {
+    return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
+}
+
+function scale(v, scale) {
+    return [v[0] * scale, v[1] * scale, v[2] * scale];
+}
+
+function cross(v1, v2) {
+    return [v1[1] * v2[2] - v1[2] * v2[1], 
+            v1[2] * v2[0] - v1[0] * v2[2],
+            v1[0] * v2[1] - v1[1] * v2[0]];
+
+}
+
+function normalise(v) {
+    var len = lengthVector(v);
+    return [v[0] / len, v[1] / len, v[2] / len];
+}
+
+function transformMatrix(self, v) {
+    var vals = self;
+    var x  = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3];
+    var y  = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7];
+    var z  = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11];
+    return [x, y, z];
+}
+
+function invertMatrix(self) {
+    var temp = new Array(16);
+    var tx = -self[3];
+    var ty = -self[7];
+    var tz = -self[11];
+    for (h = 0; h < 3; h++) 
+        for (v = 0; v < 3; v++) 
+            temp[h + v * 4] = self[v + h * 4];
+    for (i = 0; i < 11; i++)
+        self[i] = temp[i];
+    self[3] = tx * self[0] + ty * self[1] + tz * self[2];
+    self[7] = tx * self[4] + ty * self[5] + tz * self[6];
+    self[11] = tx * self[8] + ty * self[9] + tz * self[10];
+    return self;
+}
+
+
+// Triangle intersection using barycentric coord method
+function Triangle(p1, p2, p3) {
+    var edge1 = sub(p3, p1);
+    var edge2 = sub(p2, p1);
+    var normal = cross(edge1, edge2);
+    if (Math.abs(normal[0]) > Math.abs(normal[1]))
+        if (Math.abs(normal[0]) > Math.abs(normal[2]))
+            this.axis = 0; 
+        else 
+            this.axis = 2;
+    else
+        if (Math.abs(normal[1]) > Math.abs(normal[2])) 
+            this.axis = 1;
+        else 
+            this.axis = 2;
+    var u = (this.axis + 1) % 3;
+    var v = (this.axis + 2) % 3;
+    var u1 = edge1[u];
+    var v1 = edge1[v];
+    
+    var u2 = edge2[u];
+    var v2 = edge2[v];
+    this.normal = normalise(normal);
+    this.nu = normal[u] / normal[this.axis];
+    this.nv = normal[v] / normal[this.axis];
+    this.nd = dot(normal, p1) / normal[this.axis];
+    var det = u1 * v2 - v1 * u2;
+    this.eu = p1[u];
+    this.ev = p1[v]; 
+    this.nu1 = u1 / det;
+    this.nv1 = -v1 / det;
+    this.nu2 = v2 / det;
+    this.nv2 = -u2 / det; 
+    this.material = [0.7, 0.7, 0.7];
+}
+
+Triangle.prototype.intersect = function(orig, dir, near, far) {
+    var u = (this.axis + 1) % 3;
+    var v = (this.axis + 2) % 3;
+    var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v];
+    var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d;
+    if (t < near || t > far)
+        return null;
+    var Pu = orig[u] + t * dir[u] - this.eu;
+    var Pv = orig[v] + t * dir[v] - this.ev;
+    var a2 = Pv * this.nu1 + Pu * this.nv1;
+    if (a2 < 0) 
+        return null;
+    var a3 = Pu * this.nu2 + Pv * this.nv2;
+    if (a3 < 0) 
+        return null;
+
+    if ((a2 + a3) > 1) 
+        return null;
+    return t;
+}
+
+function Scene(a_triangles) {
+    this.triangles = a_triangles;
+    this.lights = [];
+    this.ambient = [0,0,0];
+    this.background = [0.8,0.8,1];
+}
+var zero = new Array(0,0,0);
+
+Scene.prototype.intersect = function(origin, dir, near, far) {
+    var closest = null;
+    for (i = 0; i < this.triangles.length; i++) {
+        var triangle = this.triangles[i];   
+        var d = triangle.intersect(origin, dir, near, far);
+        if (d == null || d > far || d < near)
+            continue;
+        far = d;
+        closest = triangle;
+    }
+    
+    if (!closest)
+        return [this.background[0],this.background[1],this.background[2]];
+        
+    var normal = closest.normal;
+    var hit = add(origin, scale(dir, far)); 
+    if (dot(dir, normal) > 0)
+        normal = [-normal[0], -normal[1], -normal[2]];
+    
+    var colour = null;
+    if (closest.shader) {
+        colour = closest.shader(closest, hit, dir);
+    } else {
+        colour = closest.material;
+    }
+    
+    // do reflection
+    var reflected = null;
+    if (colour.reflection > 0.001) {
+        var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir);
+        reflected = this.intersect(hit, reflection, 0.0001, 1000000);
+        if (colour.reflection >= 0.999999)
+            return reflected;
+    }
+    
+    var l = [this.ambient[0], this.ambient[1], this.ambient[2]];
+    for (var i = 0; i < this.lights.length; i++) {
+        var light = this.lights[i];
+        var toLight = sub(light, hit);
+        var distance = lengthVector(toLight);
+        scaleVector(toLight, 1.0/distance);
+        distance -= 0.0001;
+        if (this.blocked(hit, toLight, distance))
+            continue;
+        var nl = dot(normal, toLight);
+        if (nl > 0)
+            addVector(l, scale(light.colour, nl));
+    }
+    l = scalev(l, colour);
+    if (reflected) {
+        l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection));
+    }
+    return l;
+}
+
+Scene.prototype.blocked = function(O, D, far) {
+    var near = 0.0001;
+    var closest = null;
+    for (i = 0; i < this.triangles.length; i++) {
+        var triangle = this.triangles[i];   
+        var d = triangle.intersect(O, D, near, far);
+        if (d == null || d > far || d < near)
+            continue;
+        return true;
+    }
+    
+    return false;
+}
+
+
+// this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where
+// that somewhere is
+function Camera(origin, lookat, up) {
+    var zaxis = normaliseVector(subVector(lookat, origin));
+    var xaxis = normaliseVector(cross(up, zaxis));
+    var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis)));
+    var m = new Array(16);
+    m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2];
+    m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2];
+    m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2];
+    invertMatrix(m);
+    m[3] = 0; m[7] = 0; m[11] = 0;
+    this.origin = origin;
+    this.directions = new Array(4);
+    this.directions[0] = normalise([-0.7,  0.7, 1]);
+    this.directions[1] = normalise([ 0.7,  0.7, 1]);
+    this.directions[2] = normalise([ 0.7, -0.7, 1]);
+    this.directions[3] = normalise([-0.7, -0.7, 1]);
+    this.directions[0] = transformMatrix(m, this.directions[0]);
+    this.directions[1] = transformMatrix(m, this.directions[1]);
+    this.directions[2] = transformMatrix(m, this.directions[2]);
+    this.directions[3] = transformMatrix(m, this.directions[3]);
+}
+
+Camera.prototype.generateRayPair = function(y) {
+    rays = new Array(new Object(), new Object());
+    rays[0].origin = this.origin;
+    rays[1].origin = this.origin;
+    rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y));
+    rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y));
+    return rays;
+}
+
+function renderRows(camera, scene, pixels, width, height, starty, stopy) {
+    for (var y = starty; y < stopy; y++) {
+        var rays = camera.generateRayPair(y / height);
+        for (var x = 0; x < width; x++) {
+            var xp = x / width;
+            var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp));
+            var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp)));
+            var l = scene.intersect(origin, dir);
+            pixels[y][x] = l;
+        }
+    }
+}
+
+Camera.prototype.render = function(scene, pixels, width, height) {
+    var cam = this;
+    var row = 0;
+    renderRows(cam, scene, pixels, width, height, 0, height);
+}
+
+
+
+function raytraceScene()
+{
+    var startDate = new Date().getTime();
+    var numTriangles = 2 * 6;
+    var triangles = new Array();//numTriangles);
+    var tfl = createVector(-10,  10, -10);
+    var tfr = createVector( 10,  10, -10);
+    var tbl = createVector(-10,  10,  10);
+    var tbr = createVector( 10,  10,  10);
+    var bfl = createVector(-10, -10, -10);
+    var bfr = createVector( 10, -10, -10);
+    var bbl = createVector(-10, -10,  10);
+    var bbr = createVector( 10, -10,  10);
+    
+    // cube!!!
+    // front
+    var i = 0;
+    
+    triangles[i++] = new Triangle(tfl, tfr, bfr);
+    triangles[i++] = new Triangle(tfl, bfr, bfl);
+    // back
+    triangles[i++] = new Triangle(tbl, tbr, bbr);
+    triangles[i++] = new Triangle(tbl, bbr, bbl);
+    //        triangles[i-1].material = [0.7,0.2,0.2];
+    //            triangles[i-1].material.reflection = 0.8;
+    // left
+    triangles[i++] = new Triangle(tbl, tfl, bbl);
+    //            triangles[i-1].reflection = 0.6;
+    triangles[i++] = new Triangle(tfl, bfl, bbl);
+    //            triangles[i-1].reflection = 0.6;
+    // right
+    triangles[i++] = new Triangle(tbr, tfr, bbr);
+    triangles[i++] = new Triangle(tfr, bfr, bbr);
+    // top
+    triangles[i++] = new Triangle(tbl, tbr, tfr);
+    triangles[i++] = new Triangle(tbl, tfr, tfl);
+    // bottom
+    triangles[i++] = new Triangle(bbl, bbr, bfr);
+    triangles[i++] = new Triangle(bbl, bfr, bfl);
+    
+    //Floor!!!!
+    var green = createVector(0.0, 0.4, 0.0);
+    var grey = createVector(0.4, 0.4, 0.4);
+    grey.reflection = 1.0;
+    var floorShader = function(tri, pos, view) {
+        var x = ((pos[0]/32) % 2 + 2) % 2;
+        var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2;
+        if (x < 1 != z < 1) {
+            //in the real world we use the fresnel term...
+            //    var angle = 1-dot(view, tri.normal);
+            //   angle *= angle;
+            //  angle *= angle;
+            // angle *= angle;
+            //grey.reflection = angle;
+            return grey;
+        } else 
+            return green;
+    }
+    var ffl = createVector(-1000, -30, -1000);
+    var ffr = createVector( 1000, -30, -1000);
+    var fbl = createVector(-1000, -30,  1000);
+    var fbr = createVector( 1000, -30,  1000);
+    triangles[i++] = new Triangle(fbl, fbr, ffr);
+    triangles[i-1].shader = floorShader;
+    triangles[i++] = new Triangle(fbl, ffr, ffl);
+    triangles[i-1].shader = floorShader;
+    
+    var _scene = new Scene(triangles);
+    _scene.lights[0] = createVector(20, 38, -22);
+    _scene.lights[0].colour = createVector(0.7, 0.3, 0.3);
+    _scene.lights[1] = createVector(-23, 40, 17);
+    _scene.lights[1].colour = createVector(0.7, 0.3, 0.3);
+    _scene.lights[2] = createVector(23, 20, 17);
+    _scene.lights[2].colour = createVector(0.7, 0.7, 0.7);
+    _scene.ambient = createVector(0.1, 0.1, 0.1);
+    //  _scene.background = createVector(0.7, 0.7, 1.0);
+    
+    var size = 30;
+    var pixels = new Array();
+    for (var y = 0; y < size; y++) {
+        pixels[y] = new Array();
+        for (var x = 0; x < size; x++) {
+            pixels[y][x] = 0;
+        }
+    }
+
+    var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0));
+    _camera.render(_scene, pixels, size, size);
+
+    return pixels;
+}
+
+function arrayToCanvasCommands(pixels)
+{
+    var s = '<canvas id="renderCanvas" width="30px" height="30px"></canvas><scr' + 'ipt>\nvar pixels = [';
+    var size = 30;
+    for (var y = 0; y < size; y++) {
+        s += "[";
+        for (var x = 0; x < size; x++) {
+            s += "[" + pixels[y][x] + "],";
+        }
+        s+= "],";
+    }
+    s += '];\n    var canvas = document.getElementById("renderCanvas").getContext("2d");\n\
+\n\
+\n\
+    var size = 30;\n\
+    canvas.fillStyle = "red";\n\
+    canvas.fillRect(0, 0, size, size);\n\
+    canvas.scale(1, -1);\n\
+    canvas.translate(0, -size);\n\
+\n\
+    if (!canvas.setFillColor)\n\
+        canvas.setFillColor = function(r, g, b, a) {\n\
+            this.fillStyle = "rgb("+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+")";\n\
+    }\n\
+\n\
+for (var y = 0; y < size; y++) {\n\
+  for (var x = 0; x < size; x++) {\n\
+    var l = pixels[y][x];\n\
+    canvas.setFillColor(l[0], l[1], l[2], 1);\n\
+    canvas.fillRect(x, y, 1, 1);\n\
+  }\n\
+}</scr' + 'ipt>';
+
+    return s;
+}
+
+testOutput = arrayToCanvasCommands(raytraceScene());
+
+
+var _sunSpiderInterval = new Date() - _sunSpiderStartDate;
+
+document.getElementById("console").innerHTML = _sunSpiderInterval;
+</script>
+
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/3d-thingy.html
@@ -0,0 +1,390 @@
+<html>
+<head>
+<title>3d thingy</title>
+<style type="text/css">
+div.z2 { position:absolute; z-index:2; }
+div.z1 { position:absolute; z-index:1; }
+</style>
+<script type="text/javascript">
+/**************************************************************************
+JavaScript Graphics Library 0.0.1, Updated Source Code at Scriptersoft.com
+Copyright (C) 2005  Kurt L. Whicher
+November,13,2005
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**************************************************************************/
+
+//________________________________________ global variables
+
+var S_piDoubled=Math.PI*2;
+var S_deg2Rad=Math.PI/180;
+
+//_______________________________________________ functions
+
+function S_matrix() {
+  return [1,0,0,0,
+          0,1,0,0,
+          0,0,1,0,
+          0,0,0,1];
+}
+function S_vec2D(x,y) { this.x=x; this.y=y; }
+function S_vec3D(x,y,z) { this.x=x; this.y=y; this.z=z; }
+function S_subVec2D(a,b) {
+  return new S_vec2D(a.x-b.x, a.y-b.y);
+}
+function S_subVec3D(a,b) {
+  return new S_vec3D(a.x-b.x, a.y-b.y, a.z-b.z);
+}
+function S_dotVec3D(a, b) { return a.x*b.x+a.y*b.y+a.z*b.z; }
+function S_cross(a,b) {
+  return new S_vec3D( a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);
+}
+function S_lengthSquaredVec3D(v) { return S_dotVec3D(v,v); }
+function S_lengthVec3D(v) { return Math.sqrt(S_lengthSquaredVec3D(v)); }
+function S_normalizeVec3D(v) {
+  var l=S_lengthVec3D(v), nv=new S_vec3D(0,0,0);
+  if(l!=0) { nv.x=v.x/l; nv.y=v.y/l; nv.z=v.z/l; }
+  return nv;
+}
+function S_rotate(m,ax,a) { // transformation matrix, axis, angle
+  var i,j,ij=new Array(),v=new Array(),c=Math.cos(a),s=Math.sin(a);
+  if (ax=="x") ij=[1,2,5,6,9,10,13,14];
+  else if (ax=="y") ij=[2,0,6,4,10,8,14,12];
+  else if (ax=="z") ij=[0,1,4,5,8,9,12,13];
+  for (i=0;i<8;i++) v[i]=m[ij[i]];
+  for (i=0,j=1;i<8;i+=2,j+=2) {
+    m[ij[i]]=v[i]*c-v[j]*s;
+    m[ij[j]]=v[i]*s+v[j]*c
+  }
+}
+function S_checkBrowser() {
+  if (document.getElementById) return true; else return false;
+}
+function S_zIndex(e,z) { document.getElementById(e).style.zIndex=z; }
+function S_rgbColor(r,g,b) {
+  var i, c=[r,g,b];
+  for(i=0; i<3; i++) {
+    c[i]=Math.floor(c[i]);
+    if(c[i]<0) c[i]=0; else if(c[i]>255) c[i]=255;
+  }
+  return c;
+}
+function S_rgbColorString(c) {
+  return "rgb("+c[0]+","+c[1]+","+c[2]+")";
+}
+function S_vertice(x,y,z) {
+  this.x=x; this.y=y; this.z=z; this.w=1;
+  this.t=new S_vec3D(x,y,z); // transformed 3d
+  this.p=new S_vec2D(0,0); // projected 2d
+}
+function S_face(v0,v1,v2,c) { // 3 vertice faces
+  this.v=[v0,v1,v2]; this.c=c; this.b=0; // b:brightness
+  this.d=true; // display: true or false
+}
+// x coordinate, number of vertices, distance
+function S_verticeRing(x,nv,d) {
+  var i,a,v=new Array();
+  for(i=0;i<nv;i++) {
+    a=S_piDoubled*i/nv;
+    v[i]=new S_vertice(x,d*Math.sin(a),d*Math.cos(a));
+  }
+  return v;
+}
+function S_triangleRing(r1,r2,c,clr) { // rows 1 & 2, cols, color
+  var i,j,tr=new Array();
+  for(i=0,j=1;i<c;i++,j=++j%c) {
+    tr.push(new S_face(r1+i,r2+i,r2+j,clr));
+    tr.push(new S_face(r1+i,r2+j,r1+j,clr));
+  }
+  return tr;
+}
+function S_model(v,f) {
+  // vertice & face arrays, transformation matrix, display boolean
+  this.v=v; this.f=f, this.tm=S_matrix(), this.d=true;
+}
+S_model.prototype.S_rotateX=function(a) {
+  S_rotate(this.tm,"x",a*=S_deg2Rad);
+}
+S_model.prototype.S_rotateY=function(a) {
+  S_rotate(this.tm,"y",a*=S_deg2Rad);
+}
+S_model.prototype.S_rotateZ=function(a) {
+  S_rotate(this.tm,"z",a*=S_deg2Rad);
+}
+S_model.prototype.S_show=function() { this.d=true; }
+S_model.prototype.S_hide=function() { this.d=false; }
+function S_cube(d,c) { //distance & color
+  return new S_cone(d,d,Math.cos(Math.PI/4)*d*2,1,4,c);
+}
+function S_cylinder(w,h,r,c,clr,e) {
+  return new S_cone(w,w,h,r,c,clr,e);
+}
+// width, height, "rows", "columns", color, ends
+function S_cone(w1,w2,h,r,c,clr,e) {
+  var i,r1=0,r2=c,v=new Array(),t=new Array(),rxc=r*c;
+  for(i=0;i<=r;i++)
+    v=v.concat(S_verticeRing(h*(0.5-i/r),c,w1*i/r+w2*(r-i)/r));
+  for(i=0;i<r;i++,r1+=c,r2+=c)
+    t=t.concat(S_triangleRing(r1,r2,c,clr));
+  if (e!="hideEnds")
+    for(i=1;i<(c-1);i++) {
+      t.push(new S_face(0,i,i+1,clr));
+      t.push(new S_face(rxc,rxc+i+1,rxc+i,clr));
+    }
+  return new S_model(v,t);
+}
+function S_sphere(d,r,c,clr) {
+  // distance, "rows">=2, "columns">=3, color paramaters
+  var v=new Array(),t=new Array(),r_1xc=(r-1)*c,r_2xc=(r-2)*c;
+  var i,j,tmp,r1=0,r2=c;
+  for(i=1;i<r;i++) {
+    tmp=Math.PI*i/r;
+    v=v.concat(S_verticeRing(d*Math.cos(tmp),c,Math.sin(tmp)*d));
+  }
+  v.push(new S_vertice( d,0,0));
+  v.push(new S_vertice(-d,0,0));
+  for(i=0;i<(r-2);i++,r1+=c,r2+=c)
+    t=t.concat(S_triangleRing(r1,r2,c,clr));
+  for(i=0,j=1;i<c;i++,j=++j%c) {
+    t.push(new S_face(r_1xc,i,j,clr));
+    t.push(new S_face(r_1xc+1,r_2xc+j,r_2xc+i,clr));
+  }
+  return new S_model(v,t);
+}
+S_model.prototype.S_scale=function(x) { 
+  this.tm[0]*=x; this.tm[5]*=x; this.tm[10]*=x;
+}
+S_model.prototype.S_faceColor=function(i,c) { this.f[i].c=c; }
+S_model.prototype.S_scaleX=function(s) { this.tm[0]*=s; }
+S_model.prototype.S_scaleY=function(s) { this.tm[5]*=s; }
+S_model.prototype.S_scaleZ=function(s) { this.tm[10]*=s; }
+function S_scene(dv,l,t,w,h,cmra) { // left, top, width, height
+  this.dv=dv;
+  this.ps=1; // pixel size
+  this.l=l; this.t=t; this.w=w; this.h=h;
+  this.cx=l+w/2; this.cy=t+h/2; // center x, center y
+  this.dt="paint"; // output type
+  this.m=new Array(); // model array
+  this.lght=new S_light();
+  this.lc=S_rgbColor(255,255,255); // light color
+  this.cmra=-cmra; // camera on z axis
+  this.bfr=S_buffer(h,w);
+}
+function S_buffer(h,w) {
+  var i, j, b=new Array();
+  for(i=0;i<h;i++) {
+    b[i]=new Array();
+    for(j=0;j<w;j++) b[i][j]=new S_pixel();
+  }
+  return b;
+}
+function S_pixel() { // display boolean, color  
+  this.d=true; this.c=0;
+}
+S_pixel.prototype.S_setColor=function(c) {
+  this.d=true; this.c=c;
+}
+S_pixel.prototype.S_hide=function() { this.d=false; }
+S_scene.prototype.S_pixelSize=function(ps){ this.ps=ps; }
+S_scene.prototype.S_widthAndHeight=function(w,h){ this.w=w; this.h=h; }
+S_scene.prototype.S_center=function(cx,cy){ this.cx=cx; this.cy=cy; }
+S_scene.prototype.S_paint=function(){ this.dt="paint"; }
+S_scene.prototype.S_models=function() {
+  var i; this.m=new Array();
+  for(i=0;i<arguments.length;i++) this.m.push(arguments[i]);
+}
+S_scene.prototype.S_lightColor=function(c){ this.lc=c; }
+S_scene.prototype.S_project=function() {
+  var i, j, v, tm, d, m;
+  for(i=0;i<this.m.length;i++) {
+    m=this.m[i]; tm=this.m[i].tm;
+    for(j=0;j<m.v.length;j++) {
+      v=m.v[j];
+      v.t.x=v.x*tm[0]+v.y*tm[4]+v.z*tm[8]+v.w*tm[12];
+      v.t.y=v.x*tm[1]+v.y*tm[5]+v.z*tm[9]+v.w*tm[13];
+      v.t.z=v.x*tm[2]+v.y*tm[6]+v.z*tm[10]+v.w*tm[14];
+      d=(this.cmra-v.t.z/2);
+      if (d<0) {
+        v.p.x=(this.cmra*v.t.x/d)+this.cx;
+        v.p.y=-(this.cmra*v.t.y/d)+this.cy;
+      }
+    }
+  }
+}
+S_scene.prototype.S_display=function(disp){
+  var i, j, k, s="", ds, c, cnt=0; // ds:div start
+  this.tr=new Array(); // triangles ready to draw
+  this.S_project();
+  this.S_adjustLight();
+  this.S_clearBuffer();
+  for(i=0;i<this.m.length;i++) {
+    this.m[i].S_setupFaces(this.tr,this.lght.t);
+    for(j=0;j<this.tr.length;j++) { // loop through triangles
+      c=S_divColor(this.tr[j].c,this.lc,this.tr[j].b);
+      S_setupBuffer(this,this.tr[j].p,c);
+    }
+  }
+  for(i=0;i<this.h;i++) {
+    ds=-1;
+    for(j=0,k=1;j<this.w;j++,k++) {
+      if((this.bfr[i][j].d==true)&&(ds==-1)) ds=j;
+      if( (this.bfr[i][j].d==true)&&
+          ( (k==this.w)||
+            (this.bfr[i][k].d==false)||
+            (!S_sameColor(this.bfr[i][j].c, this.bfr[i][k].c)) ) ) {
+        s+=S_divString(S_rgbColorString(this.bfr[i][j].c),this.t+i*this.ps,this.l+ds*this.ps,this.ps,(k-ds)*this.ps);
+        ds=-1;
+        cnt++;
+      }
+    }
+  }
+  S_writeInnerHTML(this.dv,s);
+  if(disp=="ShowCount") alert(cnt);
+}
+S_scene.prototype.S_displayAndShowCount=function(){
+  this.S_display("ShowCount");
+}
+S_model.prototype.S_setupFaces=function(tr,lght) {
+  var i, j, fn, v, p=new Array(); // vertice & projection arrays
+  var z=new Array();
+  for(i=0;i<this.f.length;i++) { // loop through faces
+    v=this.f[i].v;
+    for(j=0;j<3;j++) { p[j]=this.v[v[j]].p; }
+    for(j=0;j<3;j++) { z[j]=this.v[v[j]].t.z; }
+    if (((p[1].x-p[0].x)*(p[2].y-p[0].y))<((p[2].x-p[0].x)*(p[1].y-p[0].y))) {
+      this.f[i].d=true;
+      fn=S_faceNormal(this.v[v[0]].t, this.v[v[1]].t, this.v[v[2]].t);
+      this.f[i].b=S_faceIntensity(fn,lght);
+      tr.push(new S_triangle(fn,this.f[i].b,p.slice(),this.f[i].c,z));
+    } else { this.f[i].d=false; }
+  }
+}
+// normal, brightness, array of 2D projection coordinates, and z depth
+function S_triangle(fn,b,p,c,z) {
+  this.fn=fn; this.b=b; this.p=p; this.z=z; this.c=c;
+}
+function S_faceNormal(a,b,c){
+  var cr=S_cross(S_subVec3D(b,a), S_subVec3D(b,c));
+  return S_normalizeVec3D(cr);
+}
+function S_faceIntensity(fn,lght) {
+  var i=S_dotVec3D(fn,lght); return (i>0)?i:0;
+}
+function S_divColor(c,lc,b) { // c:array of colors
+  var i, clr=new Array();
+  for(i=0;i<3;i++) clr[i]=Math.floor(c[i]+(lc[i]-c[i]+1)*b);
+  for(i=0;i<3;i++) if (clr[i]>lc[i]) { clr[i]=lc[i]; }
+  return S_rgbColor(clr[0],clr[1],clr[2]);
+}
+function S_sameColor(a,b) {
+  for(var i=0;i<3;i++) { if(a[i]!=b[i]) return false; }
+  return true;
+}
+function S_setupBuffer(scn,p,c) {
+  // temp, counters, min, max, scanline, vertice & slope arrays
+  var t,i,j,xmin=new Array(),xmax=new Array(),sl;
+  var v=new Array(), m=new Array();
+  p.sort(function(a,b) { return a.y-b.y; } );
+  for(i=0;i<3;i++) p[i].y=Math.floor(p[i].y);
+  v[0]=S_subVec2D(p[1],p[0]);
+  v[1]=S_subVec2D(p[2],p[0]);
+  v[2]=S_subVec2D(p[2],p[1]);
+  for(i=0;i<3;i++) { m[i]=(v[i].y!=0)?v[i].x/v[i].y:0; }
+  for(i=0,sl=scn.t;i<scn.h;i++,sl++) {
+    xmin[i]=1000;xmax[i]=0;
+    if((sl>=p[0].y)&&(sl<=p[2].y)) {
+      xmin[i]=xmax[i]=Math.floor(p[0].x+m[1]*(sl-p[0].y));
+    }
+    if((sl>=p[0].y)&&(sl<=p[1].y)) {
+      t=Math.floor(p[0].x+m[0]*(sl-p[0].y));
+      if(t<xmin[i]) xmin[i]=Math.floor(t);
+      else if(t>xmax[i]) xmax[i]=Math.floor(t);
+    }
+    if((sl>=p[1].y)&&(sl<=p[2].y)) {
+      t=Math.floor(p[1].x+m[2]*(sl-p[1].y));
+      if(t<xmin[i]) xmin[i]=Math.floor(t);
+      else if(t>xmax[i]) xmax[i]=Math.floor(t);
+    }
+    for(j=0;j<scn.w;j++)
+      if((j>=(xmin[i]-scn.l))&&(j<=(xmax[i]-scn.l))) {
+        scn.bfr[i][j].d=true; scn.bfr[i][j].c=c;          
+      }
+  }
+}
+function S_light() {
+  this.x=0; this.y=1; this.z=0; this.w=1; // original coordinates
+  this.t=new S_vec3D(0,1,0); // transformed coordinates
+  this.tm=new S_matrix();
+}
+S_scene.prototype.S_adjustLight=function() {
+  var m=this.lght.tm, l=this.lght;
+  l.t.x=l.x*m[0]+l.y*m[4]+ l.z*m[8]+l.w*m[12];
+  l.t.y=l.x*m[1]+l.y*m[5]+ l.z*m[9]+l.w*m[13];
+  l.t.z=l.x*m[2]+l.y*m[6]+ l.z*m[10]+l.w*m[14];
+  l.t=S_normalizeVec3D(l.t);
+}
+S_scene.prototype.S_lightRotateX=function(a) {
+  S_rotate(this.lght.tm,"x",a*=S_deg2Rad);
+}
+S_scene.prototype.S_lightRotateY=function(a) {
+  S_rotate(this.lght.tm,"y",a*=S_deg2Rad);
+}
+S_scene.prototype.S_lightRotateZ=function(a) {
+  S_rotate(this.lght.tm,"z",a*=S_deg2Rad);
+}
+S_scene.prototype.S_clearBuffer=function() {
+  for(var i=0;i<this.h;i++)
+    for(var j=0;j<this.w;j++) this.bfr[i][j].d=false;
+}
+function S_divString(b,t,l,h,w) {
+  var s='<div style="background-color:'+b+';position:absolute;';
+  s+='top:'+t+'px;left:'+l+'px;height:'+h+'px;width:'+w;
+  return s+'px;font-size:0;visibility:visible"></div>';
+}
+function S_writeInnerHTML(id,text) {
+  document.getElementById(id).innerHTML = text;
+}
+</script>
+</head>
+<body>
+<div class="z1" id="graphicsDiv">Text to be replaced with graphics.</div>
+<script type="text/javascript">
+if(S_checkBrowser()) {
+var intrvl;
+// Create a new scene with parameters for
+// div id, left, top, width, height, and camera distance
+var scn=new S_scene("graphicsDiv",75,25,100,100,300);
+scn.S_pixelSize(3); // set scene pixel size
+var c=S_rgbColor(0,0,127); // color
+var c2=S_rgbColor(0,127,127); // color
+var m=new S_cube(18,c); // model
+m.S_faceColor(4,c2);
+m.S_faceColor(5,c2);
+m.S_scaleX(2.5); // scale model along x axis
+scn.S_models(m); // add model(s) to scene
+scn.S_lightRotateX(-25); // adjust light
+function r(){ // rotation function
+m.S_rotateX(11); // rotate model around y axis
+m.S_rotateY(5); // rotate model around y axis
+m.S_rotateZ(7); // rotate model around z axis
+scn.S_display(); // display scene
+} // end rotation function
+intrvl=setInterval('r();',75);
+}
+</script>
+
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/Makefile.in
@@ -0,0 +1,82 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla PGO Input.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Robert Sayre <sayrer@gmail.com>
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_PROFILE_DIR = $(DEPTH)/_profile/pgo/js-input
+
+_PGO_FILES = 	\
+  3d-cube.html \
+  3d-morph.html \
+  3d-raytrace.html \
+  3d-thingy.html \
+  access-binary-trees.html \
+  access-fannkuch.html \
+  access-nbody.html \
+  access-nsieve.html \
+  bitops-3bit-bits-in-byte.html \
+  bitops-bits-in-byte.html \
+  bitops-bitwise-and.html \
+  bitops-nsieve-bits.html \
+  controlflow-recursive.html \
+  crypto-aes.html \
+  crypto-md5.html \
+  crypto-sha1.html \
+  crypto-otp.html \
+  date-format-tofte.html \
+  date-format-xparb.html \
+  math-cordic.html \
+  math-partial-sums.html \
+  math-spectral-norm.html \
+  regexp-dna.html \
+  string-base64.html \
+  string-fasta.html \
+  string-tagcloud.html \
+  string-unpack-code.html \
+  string-validate-input.html \
+  key.gif \
+  valid-xhtml10.png \
+  $(NULL)
+
+libs:: $(_PGO_FILES)
+	$(INSTALL) $^ $(_PROFILE_DIR)
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/access-binary-trees.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<head>
+<!--
+ Copyright (C) 2007 Apple Inc.  All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+-->
+
+<title>SunSpider access-binary-trees</title>
+
+</head>
+
+<body>
+<h3>access-binary-trees</h3>
+<div id="console">
+</div>
+
+<script>
+
+var _sunSpiderStartDate = new Date();
+
+/* The Great Computer Language Shootout
+   http://shootout.alioth.debian.org/
+   contributed by Isaac Gouy */
+
+function TreeNode(left,right,item){
+   this.left = left;
+   this.right = right;
+   this.item = item;
+}
+
+TreeNode.prototype.itemCheck = function(){
+   if (this.left==null) return this.item;
+   else return this.item + this.left.itemCheck() - this.right.itemCheck();
+}
+
+function bottomUpTree(item,depth){
+   if (depth>0){
+      return new TreeNode(
+          bottomUpTree(2*item-1, depth-1)
+         ,bottomUpTree(2*item, depth-1)
+         ,item
+      );
+   }
+   else {
+      return new TreeNode(null,null,item);
+   }
+}
+
+var ret;
+
+for ( var n = 4; n <= 7; n += 1 ) {
+    var minDepth = 4;
+    var maxDepth = Math.max(minDepth + 2, n);
+    var stretchDepth = maxDepth + 1;
+    
+    var check = bottomUpTree(0,stretchDepth).itemCheck();
+    
+    var longLivedTree = bottomUpTree(0,maxDepth);
+    for (var depth=minDepth; depth<=maxDepth; depth+=2){
+        var iterations = 1 << (maxDepth - depth + minDepth);
+
+        check = 0;
+        for (var i=1; i<=iterations; i++){
+            check += bottomUpTree(i,depth).itemCheck();
+            check += bottomUpTree(-i,depth).itemCheck();
+        }
+    }
+
+    ret = longLivedTree.itemCheck();
+}
+
+
+var _sunSpiderInterval = new Date() - _sunSpiderStartDate;
+
+document.getElementById("console").innerHTML = _sunSpiderInterval;
+</script>
+
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/build/pgo/js-input/access-fannkuch.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<head>
+<!--
+ Copyright (C) 2007 Apple Inc.  All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+-->
+
+<title>SunSpider access-fannkuch</title>
+
+</head>
+
+<body>
+<h3>access-fannkuch</h3>
+<div id="console">
+</div>
+
+<script>
+
+var _sunSpiderStartDate = new Date();
+
+/* The Great Computer Language Shootout
+   http://shootout.alioth.debian.org/
+   contributed by Isaac Gouy */
+
+function fannkuch(n) {
+   var check = 0;
+   var perm = Array(n);
+   var perm1 = Array(n);
+   var count = Array(n);
+   var maxPerm = Array(n);
+   var maxFlipsCount = 0;
+   var m = n - 1;
+
+   for (var i = 0; i < n; i++) perm1[i] = i;
+   var r = n;
+
+   while (true) {
+      // write-out the first 30 permutations
+      if (check < 30){
+         var s = "";
+         for(var i=0; i<n; i++) s += (perm1[i]+1).toString();
+         check++;
+      }
+