Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 23 Nov 2011 15:19:11 -0500
changeset 111644 7ceaa303896bae686f83081212fec143d3dfd21d
parent 111643 e06b429baa50f265530993c58c02b4b40546d7e8 (current diff)
parent 82316 0ea84b44a7f135d9bccf81c84fcf296155b053a4 (diff)
child 111645 7e1f1061a21524ec58912656df066b4c91db610c
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/msaa/nsAccessibleWrap.cpp
browser/app/application.ini
browser/app/nsBrowserApp.cpp
browser/base/content/browser.js
browser/devtools/highlighter/test/browser_inspector_highlighter.js
browser/devtools/highlighter/test/browser_inspector_iframeTest.js
browser/devtools/shared/Templater.jsm
browser/devtools/webconsole/HUDService.jsm
browser/locales/en-US/chrome/browser/devtools/inspector.properties
browser/locales/en-US/chrome/browser/devtools/styleinspector.properties
caps/src/nsSecurityManagerFactory.cpp
config/autoconf.mk.in
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsIDocument.h
content/base/src/nsContentSink.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMParser.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsStyleLinkElement.cpp
content/base/src/nsStyleLinkElement.h
content/base/src/nsTextFragment.h
content/base/src/nsTreeSanitizer.cpp
content/base/src/nsWebSocket.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/base/test/Makefile.in
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/src/nsEventStateManager.cpp
content/events/src/nsEventStateManager.h
content/events/src/nsIMEStateManager.cpp
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLLinkElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLSharedObjectElement.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/html/document/src/nsHTMLDocument.cpp
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoder.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/nsBuiltinDecoderStateMachine.h
content/media/nsMediaDecoder.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGFilters.h
content/svg/content/src/nsSVGImageElement.cpp
content/svg/content/src/nsSVGPathElement.cpp
content/svg/content/src/nsSVGPathElement.h
content/svg/content/src/nsSVGScriptElement.cpp
content/xbl/src/nsXBLProtoImplField.cpp
content/xbl/src/nsXBLProtoImplProperty.h
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLDocument.cpp
content/xslt/src/base/txCore.h
content/xslt/src/base/txList.h
content/xslt/src/xml/txDOM.h
content/xslt/src/xpath/txCoreFunctionCall.cpp
content/xslt/src/xpath/txExprParser.cpp
content/xslt/src/xpath/txLiteralExpr.cpp
content/xslt/src/xpath/txNodeSet.cpp
content/xslt/src/xpath/txNumberExpr.cpp
content/xslt/src/xpath/txUnionNodeTest.cpp
content/xslt/src/xslt/txEXSLTFunctions.cpp
content/xslt/src/xslt/txFormatNumberFunctionCall.cpp
content/xslt/src/xslt/txInstructions.h
content/xslt/src/xslt/txNodeSorter.cpp
content/xslt/src/xslt/txNodeSorter.h
content/xslt/src/xslt/txRtfHandler.cpp
content/xslt/src/xslt/txStylesheet.cpp
content/xslt/src/xslt/txStylesheet.h
content/xslt/src/xslt/txStylesheetCompileHandlers.cpp
content/xslt/src/xslt/txStylesheetCompiler.cpp
content/xslt/src/xslt/txStylesheetCompiler.h
content/xslt/src/xslt/txXSLTNumber.cpp
content/xslt/src/xslt/txXSLTPatterns.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSEnvironment.cpp
dom/base/nsPIDOMWindow.h
dom/indexedDB/AsyncConnectionHelper.cpp
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBEvents.cpp
dom/indexedDB/IDBEvents.h
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/indexedDB/IDBTransaction.cpp
dom/locales/en-US/chrome/dom/dom.properties
dom/plugins/base/nsPluginHost.cpp
dom/system/NetworkGeolocationProvider.js
dom/workers/RuntimeService.cpp
dom/workers/XMLHttpRequestPrivate.cpp
editor/libeditor/base/nsEditor.cpp
embedding/android/AndroidManifest.xml.in
embedding/android/GeckoApp.java
gfx/angle/README.mozilla
gfx/angle/angle-intrinsic-msvc2005.patch
gfx/angle/angle-renaming-debug.patch
gfx/angle/src/common/version.h
gfx/angle/src/libEGL/Display.cpp
gfx/angle/src/libEGL/Display.h
gfx/angle/src/libEGL/Surface.cpp
gfx/angle/src/libGLESv2/Context.cpp
gfx/angle/src/libGLESv2/Context.h
gfx/angle/src/libGLESv2/Program.cpp
gfx/angle/src/libGLESv2/Program.h
gfx/angle/src/libGLESv2/VertexDataManager.cpp
gfx/angle/src/libGLESv2/libGLESv2.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLContextProviderOSMesa.cpp
gfx/gl/GLContextProviderWGL.cpp
gfx/gl/GLXLibrary.h
gfx/gl/WGLLibrary.h
gfx/layers/basic/BasicLayers.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/thebes/EGLUtils.h
gfx/thebes/GLContext.cpp
gfx/thebes/GLContext.h
gfx/thebes/GLContextProvider.h
gfx/thebes/GLContextProviderCGL.mm
gfx/thebes/GLContextProviderEGL.cpp
gfx/thebes/GLContextProviderGLX.cpp
gfx/thebes/GLContextProviderImpl.h
gfx/thebes/GLContextProviderNull.cpp
gfx/thebes/GLContextProviderOSMesa.cpp
gfx/thebes/GLContextProviderWGL.cpp
gfx/thebes/GLContextSymbols.h
gfx/thebes/GLDefs.h
gfx/thebes/GLXLibrary.h
gfx/thebes/WGLLibrary.h
gfx/thebes/gfxBlur.cpp
gfx/thebes/gfxBlur.h
gfx/thebes/gfxUserFontSet.cpp
ipc/ipdl/ipdl/builtin.py
js/src/Makefile.in
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
js/src/gc/Barrier.h
js/src/imacro_asm.py
js/src/imacros.jsasm
js/src/jit-test/jit_test.py
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsarray.h
js/src/jsbuiltins.cpp
js/src/jsbuiltins.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcmark.cpp
js/src/jsgcstats.cpp
js/src/jshotloop.h
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcode.tbl
js/src/jsprobes.cpp
js/src/jspropertycache.cpp
js/src/jsprvtd.h
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jstracer.cpp
js/src/jstracer.h
js/src/jstypedarray.cpp
js/src/jsutil.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/jsxml.cpp
js/src/lirasm/LInsClasses.tbl
js/src/lirasm/Makefile.in
js/src/lirasm/lirasm.cpp
js/src/lirasm/testlirc.sh
js/src/lirasm/tests/32-bit/many_params.in
js/src/lirasm/tests/32-bit/many_params.out
js/src/lirasm/tests/64-bit/dasq.in
js/src/lirasm/tests/64-bit/dasq.out
js/src/lirasm/tests/64-bit/qasd.in
js/src/lirasm/tests/64-bit/qasd.out
js/src/lirasm/tests/64-bit/shq.in
js/src/lirasm/tests/64-bit/shq.out
js/src/lirasm/tests/add.in
js/src/lirasm/tests/add.out
js/src/lirasm/tests/addd.in
js/src/lirasm/tests/addd.out
js/src/lirasm/tests/addjovi.in
js/src/lirasm/tests/addjovi.out
js/src/lirasm/tests/addjovi_ovf.in
js/src/lirasm/tests/addjovi_ovf.out
js/src/lirasm/tests/addsub.in
js/src/lirasm/tests/addsub.out
js/src/lirasm/tests/backjump.in
js/src/lirasm/tests/backjump.out
js/src/lirasm/tests/bigendian/fuzz-527178.in
js/src/lirasm/tests/bigendian/fuzz-527178.out
js/src/lirasm/tests/bigendian/ldc2i.in
js/src/lirasm/tests/bigendian/ldc2i.out
js/src/lirasm/tests/bigendian/lds2i.in
js/src/lirasm/tests/bigendian/lds2i.out
js/src/lirasm/tests/bigendian/lduc2ui.in
js/src/lirasm/tests/bigendian/lduc2ui.out
js/src/lirasm/tests/bigendian/ldus2ui.in
js/src/lirasm/tests/bigendian/ldus2ui.out
js/src/lirasm/tests/bug596923.in
js/src/lirasm/tests/bug596923.out
js/src/lirasm/tests/bug643969.in
js/src/lirasm/tests/bug643969.out
js/src/lirasm/tests/call1.in
js/src/lirasm/tests/call1.out
js/src/lirasm/tests/call2.in
js/src/lirasm/tests/call2.out
js/src/lirasm/tests/calld1.in
js/src/lirasm/tests/calld1.out
js/src/lirasm/tests/callid1.in
js/src/lirasm/tests/callid1.out
js/src/lirasm/tests/callid2.in
js/src/lirasm/tests/callid2.out
js/src/lirasm/tests/callid3.in
js/src/lirasm/tests/callid3.out
js/src/lirasm/tests/callv.in
js/src/lirasm/tests/callv.out
js/src/lirasm/tests/cmov.in
js/src/lirasm/tests/cmov.out
js/src/lirasm/tests/cond_eqd.in
js/src/lirasm/tests/cond_eqd.out
js/src/lirasm/tests/cond_eqi.in
js/src/lirasm/tests/cond_eqi.out
js/src/lirasm/tests/cond_ged.in
js/src/lirasm/tests/cond_ged.out
js/src/lirasm/tests/cond_gei.in
js/src/lirasm/tests/cond_gei.out
js/src/lirasm/tests/cond_geui.in
js/src/lirasm/tests/cond_geui.out
js/src/lirasm/tests/cond_gtd.in
js/src/lirasm/tests/cond_gtd.out
js/src/lirasm/tests/cond_gti.in
js/src/lirasm/tests/cond_gti.out
js/src/lirasm/tests/cond_gtui.in
js/src/lirasm/tests/cond_gtui.out
js/src/lirasm/tests/cond_led.in
js/src/lirasm/tests/cond_led.out
js/src/lirasm/tests/cond_lei.in
js/src/lirasm/tests/cond_lei.out
js/src/lirasm/tests/cond_leui.in
js/src/lirasm/tests/cond_leui.out
js/src/lirasm/tests/cond_ltd.in
js/src/lirasm/tests/cond_ltd.out
js/src/lirasm/tests/cond_lti.in
js/src/lirasm/tests/cond_lti.out
js/src/lirasm/tests/cond_ltui.in
js/src/lirasm/tests/cond_ltui.out
js/src/lirasm/tests/divd.in
js/src/lirasm/tests/divd.out
js/src/lirasm/tests/float_double.in
js/src/lirasm/tests/float_double.out
js/src/lirasm/tests/floatingpoint.in
js/src/lirasm/tests/floatingpoint.out
js/src/lirasm/tests/fneg.in
js/src/lirasm/tests/fneg.out
js/src/lirasm/tests/fpu1-598151.in
js/src/lirasm/tests/fpu1-598151.out
js/src/lirasm/tests/fpu2-598151.in
js/src/lirasm/tests/fpu2-598151.out
js/src/lirasm/tests/fuzz-527178.in
js/src/lirasm/tests/fuzz-527178.out
js/src/lirasm/tests/hardfloat/d2i.in
js/src/lirasm/tests/hardfloat/d2i.out
js/src/lirasm/tests/hardfloat/f2i.in
js/src/lirasm/tests/hardfloat/f2i.out
js/src/lirasm/tests/hardfloat/i2d.in
js/src/lirasm/tests/hardfloat/i2d.out
js/src/lirasm/tests/hardfloat/ui2d.in
js/src/lirasm/tests/hardfloat/ui2d.out
js/src/lirasm/tests/largeframe.in
js/src/lirasm/tests/largeframe.out
js/src/lirasm/tests/ldc2i.in
js/src/lirasm/tests/ldc2i.out
js/src/lirasm/tests/lds2i.in
js/src/lirasm/tests/lds2i.out
js/src/lirasm/tests/lduc2ui.in
js/src/lirasm/tests/lduc2ui.out
js/src/lirasm/tests/ldus2ui.in
js/src/lirasm/tests/ldus2ui.out
js/src/lirasm/tests/littleendian/fuzz-527178.in
js/src/lirasm/tests/littleendian/fuzz-527178.out
js/src/lirasm/tests/littleendian/ldc2i.in
js/src/lirasm/tests/littleendian/ldc2i.out
js/src/lirasm/tests/littleendian/lds2i.in
js/src/lirasm/tests/littleendian/lds2i.out
js/src/lirasm/tests/littleendian/lduc2ui.in
js/src/lirasm/tests/littleendian/lduc2ui.out
js/src/lirasm/tests/littleendian/ldus2ui.in
js/src/lirasm/tests/littleendian/ldus2ui.out
js/src/lirasm/tests/loadstore.in
js/src/lirasm/tests/loadstore.out
js/src/lirasm/tests/mul_xxx.in
js/src/lirasm/tests/mul_xxx.out
js/src/lirasm/tests/mul_xxy.in
js/src/lirasm/tests/mul_xxy.out
js/src/lirasm/tests/mul_xyy.in
js/src/lirasm/tests/mul_xyy.out
js/src/lirasm/tests/mul_xyz.in
js/src/lirasm/tests/mul_xyz.out
js/src/lirasm/tests/muld.in
js/src/lirasm/tests/muld.out
js/src/lirasm/tests/muljovi.in
js/src/lirasm/tests/muljovi.out
js/src/lirasm/tests/muljovi_ovf.in
js/src/lirasm/tests/muljovi_ovf.out
js/src/lirasm/tests/muljovi_xxx.in
js/src/lirasm/tests/muljovi_xxx.out
js/src/lirasm/tests/muljovi_xxy.in
js/src/lirasm/tests/muljovi_xxy.out
js/src/lirasm/tests/muljovi_xyy.in
js/src/lirasm/tests/muljovi_xyy.out
js/src/lirasm/tests/muljovi_xyz.in
js/src/lirasm/tests/muljovi_xyz.out
js/src/lirasm/tests/mulov_xxx.in
js/src/lirasm/tests/mulov_xxx.out
js/src/lirasm/tests/mulov_xxy.in
js/src/lirasm/tests/mulov_xxy.out
js/src/lirasm/tests/mulov_xyy.in
js/src/lirasm/tests/mulov_xyy.out
js/src/lirasm/tests/mulov_xyz.in
js/src/lirasm/tests/mulov_xyz.out
js/src/lirasm/tests/multfrag1.in
js/src/lirasm/tests/multfrag1.out
js/src/lirasm/tests/multfrag2.in
js/src/lirasm/tests/multfrag2.out
js/src/lirasm/tests/multfrag3.in
js/src/lirasm/tests/multfrag3.out
js/src/lirasm/tests/negnot.in
js/src/lirasm/tests/negnot.out
js/src/lirasm/tests/random.out
js/src/lirasm/tests/shi.in
js/src/lirasm/tests/shi.out
js/src/lirasm/tests/softfloat/dhi2i.in
js/src/lirasm/tests/softfloat/dhi2i.out
js/src/lirasm/tests/softfloat/dlo2i.in
js/src/lirasm/tests/softfloat/dlo2i.out
js/src/lirasm/tests/softfloat/ii2d.in
js/src/lirasm/tests/softfloat/ii2d.out
js/src/lirasm/tests/std2f.in
js/src/lirasm/tests/std2f.out
js/src/lirasm/tests/subd.in
js/src/lirasm/tests/subd.out
js/src/lirasm/tests/subjovi.in
js/src/lirasm/tests/subjovi.out
js/src/lirasm/tests/subjovi_ovf.in
js/src/lirasm/tests/subjovi_ovf.out
js/src/methodjit/Compiler.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/nanojit-import-filemap
js/src/nanojit-import-rev
js/src/nanojit/Allocator.cpp
js/src/nanojit/Allocator.h
js/src/nanojit/Assembler.cpp
js/src/nanojit/Assembler.h
js/src/nanojit/CodeAlloc.cpp
js/src/nanojit/CodeAlloc.h
js/src/nanojit/Containers.cpp
js/src/nanojit/Containers.h
js/src/nanojit/Fragmento.cpp
js/src/nanojit/Fragmento.h
js/src/nanojit/LIR.cpp
js/src/nanojit/LIR.h
js/src/nanojit/LIRopcode.tbl
js/src/nanojit/Native.h
js/src/nanojit/NativeARM.cpp
js/src/nanojit/NativeARM.h
js/src/nanojit/NativeCommon.h
js/src/nanojit/NativeMIPS.cpp
js/src/nanojit/NativeMIPS.h
js/src/nanojit/NativePPC.cpp
js/src/nanojit/NativePPC.h
js/src/nanojit/NativeSH4-auto-generated.h
js/src/nanojit/NativeSH4.cpp
js/src/nanojit/NativeSH4.h
js/src/nanojit/NativeSparc.cpp
js/src/nanojit/NativeSparc.h
js/src/nanojit/NativeX64.cpp
js/src/nanojit/NativeX64.h
js/src/nanojit/Nativei386.cpp
js/src/nanojit/Nativei386.h
js/src/nanojit/RegAlloc.cpp
js/src/nanojit/RegAlloc.h
js/src/nanojit/VMPI.cpp
js/src/nanojit/VMPI.h
js/src/nanojit/avmplus.cpp
js/src/nanojit/avmplus.h
js/src/nanojit/manifest.mk
js/src/nanojit/nanojit.h
js/src/nanojit/njconfig.cpp
js/src/nanojit/njconfig.h
js/src/nanojit/njcpudetect.h
js/src/shell/js.cpp
js/src/shell/jsworkers.cpp
js/src/tests/js1_8_5/regress/jstests.list
js/src/tracejit/Writer-inl.h
js/src/tracejit/Writer.cpp
js/src/tracejit/Writer.h
js/src/tracevis/README
js/src/tracevis/acts.py
js/src/tracevis/binlog.py
js/src/tracevis/config.py
js/src/tracevis/tree.py
js/src/tracevis/vis.py
js/src/vm/RegExpObject-inl.h
js/src/vm/RegExpObject.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/StackSpace.h
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/Makefile.in
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeInfo.cpp
js/xpconnect/src/XPCWrappedNativeProto.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsIPresShell.h
layout/base/nsImageLoader.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.cpp
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/base/tests/Makefile.in
layout/base/tests/test_reftests_with_caret.html
layout/generic/nsContainerFrame.cpp
layout/generic/nsFloatManager.h
layout/generic/nsFrame.cpp
layout/generic/nsFrameSelection.h
layout/generic/nsLineBox.h
layout/generic/nsQueryFrame.h
layout/generic/nsSelection.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/reftests/abs-pos/reftest.list
layout/reftests/canvas/reftest.list
layout/reftests/reftest-sanity/reftest.list
layout/reftests/svg/reftest.list
layout/style/StyleRule.h
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsCSSStyleSheet.h
layout/svg/base/src/SVGFELeafFrame.cpp
layout/svg/base/src/nsSVGGeometryFrame.cpp
layout/xul/base/public/nsXULPopupManager.h
layout/xul/base/src/nsXULPopupManager.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.h
memory/jemalloc/jemalloc.c
mobile/xul/app/application.ini
mobile/xul/app/nsBrowserApp.cpp
mobile/xul/chrome/content/browser.js
mobile/xul/confvars.sh
modules/libpref/src/init/all.js
netwerk/base/src/nsProtocolProxyService.cpp
netwerk/dns/nsHostResolver.h
netwerk/mime/nsMIMEHeaderParamImpl.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.h
other-licenses/android/APKOpen.cpp
other-licenses/android/Makefile.in
parser/html/nsHtml5AttributeName.cpp
parser/html/nsHtml5AttributeName.h
parser/html/nsHtml5Parser.cpp
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5StreamParser.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
parser/htmlparser/public/nsIParser.h
startupcache/test/TestStartupCache.cpp
testing/jetpack/jetpack-location.txt
testing/xpcshell/xpcshell.ini
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/autocomplete/nsAutoCompleteController.h
toolkit/components/satchel/nsFormFillController.cpp
toolkit/components/satchel/nsFormFillController.h
toolkit/components/startup/nsAppStartup.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/components/telemetry/TelemetryPing.js
toolkit/content/license.html
toolkit/content/widgets/videocontrols.xml
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/installer/packager.mk
toolkit/mozapps/update/nsUpdateService.js
toolkit/xre/nsAndroidStartup.cpp
toolkit/xre/nsAppRunner.cpp
view/public/nsIView.h
view/public/nsIViewManager.h
view/public/nsIViewObserver.h
view/src/nsView.cpp
view/src/nsViewManager.cpp
view/src/nsViewManager.h
widget/public/nsIWidget.h
widget/src/android/AndroidBridge.cpp
widget/src/android/AndroidBridge.h
widget/src/android/AndroidJNI.cpp
widget/src/android/GfxInfo.cpp
widget/src/android/GfxInfo.h
widget/src/android/nsAppShell.cpp
widget/src/android/nsWindow.cpp
widget/src/android/nsWindow.h
widget/src/cocoa/GfxInfo.h
widget/src/cocoa/GfxInfo.mm
widget/src/cocoa/nsAppShell.mm
widget/src/cocoa/nsChildView.mm
widget/src/gtk2/nsAppShell.cpp
widget/src/gtk2/nsWindow.cpp
widget/src/windows/GfxInfo.cpp
widget/src/windows/GfxInfo.h
widget/src/windows/nsAppShell.cpp
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/xpwidgets/GfxInfoX11.cpp
widget/src/xpwidgets/GfxInfoX11.h
widget/src/xpwidgets/nsBaseDragService.cpp
widget/src/xpwidgets/nsBaseWidget.cpp
widget/src/xpwidgets/nsBaseWidget.h
xpcom/base/nsMemoryImpl.cpp
xpcom/base/nsMemoryReporterManager.cpp
xpcom/build/BinaryPath.h
xpcom/build/nsXPComInit.cpp
xpcom/glue/nsArrayEnumerator.cpp
xpcom/glue/nsCOMPtr.h
xpcom/glue/nsEnumeratorUtils.cpp
xpcom/idl-parser/xpidl.py
xpcom/io/nsStorageStream.cpp
xpcom/tests/TestTArray.cpp
xpcom/threads/nsThread.cpp
xpcom/threads/nsThread.h
xpcom/threads/nsThreadManager.cpp
xpfe/appshell/src/nsAppShellService.cpp
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1582,16 +1582,23 @@ nsAccessibleWrap::FirePlatformEvent(AccE
 #ifdef DEBUG_A11Y
   printf("\n\nMSAA event: event: %d, target: %s@id='%s', childid: %d, hwnd: %d\n\n",
          eventType, NS_ConvertUTF16toUTF8(tag).get(), id.get(),
          childID, hWnd);
 #endif
 
   // Fire MSAA event for client area window.
   NotifyWinEvent(winEvent, hWnd, OBJID_CLIENT, childID);
+
+  // JAWS announces collapsed combobox navigation based on focus events.
+  if (eventType == nsIAccessibleEvent::EVENT_SELECTION &&
+      accessible->Role() == nsIAccessibleRole::ROLE_COMBOBOX_OPTION &&
+      nsWinUtils::IsWindowEmulationFor(kJAWSModuleHandle)) {
+    NotifyWinEvent(EVENT_OBJECT_FOCUS, hWnd, OBJID_CLIENT, childID);
+  }
   return NS_OK;
 }
 
 //------- Helper methods ---------
 
 PRInt32 nsAccessibleWrap::GetChildIDFor(nsAccessible* aAccessible)
 {
   // A child ID of the window is required, when we use NotifyWinEvent,
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -56,52 +56,29 @@ PREF_JS_EXPORTS = $(srcdir)/profile/fire
 # hardcode en-US for the moment
 AB_CD = en-US
 
 DEFINES += -DAB_CD=$(AB_CD)
 
 APP_VERSION = $(shell cat $(srcdir)/../config/version.txt)
 DEFINES += -DAPP_VERSION="$(APP_VERSION)"
 
-DIST_FILES = application.ini
-
-GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
-GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
-
-DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
-
-MOZ_SOURCE_STAMP ?= $(shell hg -R $(topsrcdir) parent --template="{node|short}\n" 2>/dev/null)
-ifdef MOZ_SOURCE_STAMP
-DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
-endif
-
-SOURCE_REPO := $(shell hg -R $(topsrcdir) showconfig paths.default 2>/dev/null | sed -e "s/^ssh:/http:/")
-ifdef SOURCE_REPO
-DEFINES += -DMOZ_SOURCE_REPO="$(SOURCE_REPO)"
-endif
-
-DEFINES += -DMOZ_APP_BASENAME="$(MOZ_APP_BASENAME)" \
-           -DMOZ_APP_VENDOR="$(MOZ_APP_VENDOR)"
-
-ifdef MOZ_APP_PROFILE
-DEFINES += -DMOZ_APP_PROFILE="$(MOZ_APP_PROFILE)"
-endif
-
 ifdef LIBXUL_SDK
 include $(topsrcdir)/config/rules.mk
 else
 # Build a binary bootstrapping with XRE_main
 
 PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
+LOCAL_INCLUDES += -I$(DEPTH)/build
 
 DEFINES += -DXPCOM_GLUE
 STL_FLAGS=
 
 LIBS += \
 	$(EXTRA_DSO_LIBS) \
 	$(XPCOM_STANDALONE_GLUE_LDOPTS) \
 	$(NULL)
@@ -182,20 +159,16 @@ libs::
 GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/, firefox.js)
 
 endif
 
 endif # LIBXUL_SDK
 
 DEFINES += -DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\"
 
-ifdef MOZILLA_OFFICIAL
-DEFINES += -DMOZILLA_OFFICIAL
-endif
-
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 libs::
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(DIST)/bin/icons
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png  $(DIST)/bin/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png  $(DIST)/bin/chrome/icons/default
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png  $(DIST)/bin/chrome/icons/default
 endif
 
@@ -223,17 +196,17 @@ clean clobber repackage::
 	$(RM) -r $(DIST)/$(APP_NAME).app
 
 ifdef LIBXUL_SDK
 APPFILES = Resources
 else
 APPFILES = MacOS
 endif
 
-libs repackage:: $(PROGRAM) application.ini
+libs repackage:: $(PROGRAM)
 	$(MKDIR) -p $(DIST)/$(APP_NAME).app/Contents/MacOS
 	rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
 	$(MKDIR) -p $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%LOWER_APP_NAME%/$(LOWER_APP_NAME)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
 	sed -e "s/%APP_NAME%/$(APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj/InfoPlist.strings
 	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -31,18 +31,18 @@
  * 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 ***** */
 
+#include "application.ini.h"
 #include "nsXPCOMGlue.h"
-#include "nsXULAppAPI.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #elif defined(XP_UNIX)
 #include <sys/time.h>
 #include <sys/resource.h>
 #endif
 
@@ -135,30 +135,17 @@ static const nsDynamicFunctionLoad kXULF
     { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
     { "XRE_main", (NSFuncPtr*) &XRE_main },
     { nsnull, nsnull }
 };
 
 static int do_main(const char *exePath, int argc, char* argv[])
 {
   nsCOMPtr<nsILocalFile> appini;
-#ifdef XP_WIN
-  // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
-  // encoded path, so it is safe to convert it
-  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
-                                getter_AddRefs(appini));
-#else
-  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
-                                      getter_AddRefs(appini));
-#endif
-  if (NS_FAILED(rv)) {
-    return 255;
-  }
-
-  appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
+  nsresult rv;
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
   const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
     rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("Invalid path found: '%s'", appDataFile);
@@ -183,25 +170,42 @@ static int do_main(const char *exePath, 
       Output("Couldn't set %s.\n", appEnv);
       return 255;
     }
     argv[2] = argv[0];
     argv += 2;
     argc -= 2;
   }
 
-  nsXREAppData *appData;
-  rv = XRE_CreateAppData(appini, &appData);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't read application.ini");
-    return 255;
+  int result;
+  if (appini) {
+    nsXREAppData *appData;
+    rv = XRE_CreateAppData(appini, &appData);
+    if (NS_FAILED(rv)) {
+      Output("Couldn't read application.ini");
+      return 255;
+    }
+    result = XRE_main(argc, argv, appData);
+    XRE_FreeAppData(appData);
+  } else {
+#ifdef XP_WIN
+    // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
+    // encoded path, so it is safe to convert it
+    rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE,
+                         getter_AddRefs(appini));
+#else
+    rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE,
+                               getter_AddRefs(appini));
+#endif
+    if (NS_FAILED(rv)) {
+      return 255;
+    }
+    result = XRE_main(argc, argv, &sAppData);
   }
 
-  int result = XRE_main(argc, argv, appData);
-  XRE_FreeAppData(appData);
   return result;
 }
 
 int main(int argc, char* argv[])
 {
   char exePath[MAXPATHLEN];
 
   nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
@@ -235,16 +239,18 @@ int main(int argc, char* argv[])
   }
 
 
   rv = XPCOMGlueStartup(exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XPCOM.\n");
     return 255;
   }
+  // Reset exePath so that it is the directory name and not the xpcom dll name
+  *lastSlash = 0;
 
   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XRE functions.\n");
     return 255;
   }
 
 #ifdef XRE_HAS_DLL_BLOCKLIST
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3926,24 +3926,23 @@ var FullScreen = {
       return;
     }
 
     // We receive "mozfullscreenchange" events for each subdocument which
     // is an ancestor of the document containing the element which requested
     // full-screen. Only add listeners and show warning etc when the event we
     // receive is targeted at the chrome document, i.e. only once every time
     // we enter DOM full-screen mode.
-    let targetDoc = event.target.ownerDocument ? event.target.ownerDocument : event.target;
-    if (targetDoc != document) {
+    if (event.target != document) {
       // However, if we receive a "mozfullscreenchange" event for a document
       // which is not a subdocument of the currently selected tab, we know that
       // we've switched tabs since the request to enter full-screen was made,
       // so we should exit full-screen since the "full-screen document" isn't
       // acutally visible.
-      if (targetDoc.defaultView.top != gBrowser.contentWindow) {
+      if (event.target.defaultView.top != gBrowser.contentWindow) {
         document.mozCancelFullScreen();
       }
       return;
     }
 
     let focusManger = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
     if (focusManger.activeWindow != window) {
       // The top-level window has lost focus since the request to enter
--- a/browser/config/mozconfigs/linux32/debug
+++ b/browser/config/mozconfigs/linux32/debug
@@ -1,13 +1,13 @@
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig
@@ -1,7 +1,7 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
-CC=/tools/gcc-4.3.3/installed/bin/gcc
-CXX=/tools/gcc-4.3.3/installed/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
--- a/browser/config/mozconfigs/linux32/nightly
+++ b/browser/config/mozconfigs/linux32/nightly
@@ -1,17 +1,17 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux32/qt
+++ b/browser/config/mozconfigs/linux32/qt
@@ -1,13 +1,13 @@
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # PGO
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
--- a/browser/config/mozconfigs/linux32/release
+++ b/browser/config/mozconfigs/linux32/release
@@ -1,14 +1,14 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-official-branding
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # PGO
 mk_add_options MOZ_PGO=1
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
 
 # Needed to enable breakpad in application.ini
--- a/browser/config/mozconfigs/linux32/rpm
+++ b/browser/config/mozconfigs/linux32/rpm
@@ -4,18 +4,18 @@ ac_add_options --enable-codesighs
 # Options for rpm versions of mozconfigs
 PREFIX=/usr
 LIBDIR=${PREFIX}/lib
 ac_add_options --with-app-name=mozilla-nightly
 ac_add_options --disable-updater
 ac_add_options --prefix=$PREFIX
 ac_add_options --libdir=$LIBDIR
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux64/debug
+++ b/browser/config/mozconfigs/linux64/debug
@@ -1,13 +1,13 @@
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig
@@ -1,7 +1,7 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
-CC=/tools/gcc/bin/gcc
-CXX=/tools/gcc/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
--- a/browser/config/mozconfigs/linux64/nightly
+++ b/browser/config/mozconfigs/linux64/nightly
@@ -1,17 +1,17 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux64/release
+++ b/browser/config/mozconfigs/linux64/release
@@ -1,14 +1,14 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-official-branding
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # PGO
 mk_add_options MOZ_PGO=1
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
 
 # Needed to enable breakpad in application.ini
--- a/browser/config/mozconfigs/linux64/rpm
+++ b/browser/config/mozconfigs/linux64/rpm
@@ -4,18 +4,18 @@ ac_add_options --enable-codesighs
 # Options for rpm versions of mozconfigs
 PREFIX=/usr
 LIBDIR=${PREFIX}/lib64
 ac_add_options --with-app-name=mozilla-nightly
 ac_add_options --disable-updater
 ac_add_options --prefix=$PREFIX
 ac_add_options --libdir=$LIBDIR
 
-CC=/tools/gcc-4.5/bin/gcc
-CXX=/tools/gcc-4.5/bin/g++
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -46,8 +46,12 @@ MOZ_SAFE_BROWSING=1
 MOZ_SERVICES_SYNC=1
 MOZ_APP_VERSION=$FIREFOX_VERSION
 MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
 # MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
 # Changing either of these values requires a clobber to ensure correct results,
 # because branding dependencies are broken.
 MOZ_BRANDING_DIRECTORY=browser/branding/nightly
 MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
+MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+MOZ_PROFILE_MIGRATOR=1
+MOZ_EXTENSION_MANAGER=1
+MOZ_APP_STATIC_INI=1
--- a/browser/devtools/highlighter/TreePanel.jsm
+++ b/browser/devtools/highlighter/TreePanel.jsm
@@ -40,17 +40,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const Cu = Components.utils;
 
 Cu.import("resource:///modules/domplate.jsm");
 Cu.import("resource:///modules/InsideOutBox.jsm");
-Cu.import("resource:///modules/Services.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var EXPORTED_SYMBOLS = ["TreePanel", "DOMHelpers"];
 
 const INSPECTOR_URI = "chrome://browser/content/inspector.html";
 
 /**
  * TreePanel
  * A container for the Inspector's HTML Tree Panel widget constructor function.
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -21,16 +21,17 @@
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Rob Campbell <rcampbell@mozilla.com> (original author)
  *   Mihai Șucan <mihai.sucan@gmail.com>
  *   Julian Viereck <jviereck@mozilla.com>
  *   Paul Rouget <paul@mozilla.com>
  *   Kyle Simpson <ksimpson@mozilla.com>
+ *   Johan Charlez <johan.charlez@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
@@ -1107,18 +1108,18 @@ InspectorUI.prototype = {
   {
     if (!this.inspecting) {
       return;
     }
 
     this.inspectToolbutton.checked = false;
     // Detach event listeners from content window and child windows to disable
     // highlighting. We still want to be notified if the user presses "ESCAPE"
-    // to unlock the node, so we don't remove the "keypress" event until
-    // the highlighter is removed.
+    // to close the inspector, or "RETURN" to unlock the node, so we don't 
+    // remove the "keypress" event until the highlighter is removed.
     this.highlighter.detachInspectListeners();
 
     this.inspecting = false;
     this.toolsDim(false);
     if (this.highlighter.node) {
       this.select(this.highlighter.node, true, true, !aPreventScroll);
     } else {
       this.select(null, true, true);
@@ -1181,17 +1182,18 @@ InspectorUI.prototype = {
 
     if (this.store.getValue(this.winID, "inspecting")) {
       this.startInspecting();
     }
 
     this.restoreToolState(this.winID);
 
     this.win.focus();
-    Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.OPENED, null);
+    Services.obs.notifyObservers({wrappedJSObject: this},
+                                 INSPECTOR_NOTIFICATIONS.OPENED, null);
   },
 
   /**
    * Main callback handler for events.
    *
    * @param event
    *        The event to be handled.
    */
@@ -1243,18 +1245,22 @@ InspectorUI.prototype = {
 
         if (this.store.isEmpty()) {
           this.tabbrowser.tabContainer.removeEventListener("TabSelect", this,
                                                          false);
         }
         break;
       case "keypress":
         switch (event.keyCode) {
+          case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
+            this.closeInspectorUI(false);
+            event.preventDefault();
+            event.stopPropagation();
+            break;
           case this.chromeWin.KeyEvent.DOM_VK_RETURN:
-          case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
             this.toggleInspection();
             event.preventDefault();
             event.stopPropagation();
             break;
           case this.chromeWin.KeyEvent.DOM_VK_LEFT:
             let node;
             if (this.selection) {
               node = this.selection.parentNode;
--- a/browser/devtools/highlighter/test/browser_inspector_highlighter.js
+++ b/browser/devtools/highlighter/test/browser_inspector_highlighter.js
@@ -89,21 +89,24 @@ function setupHighlighterTests()
 {
   h1 = doc.querySelector("h1");
   ok(h1, "we have the header");
   Services.obs.addObserver(runSelectionTests,
     InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
   InspectorUI.toggleInspectorUI();
 }
 
-function runSelectionTests()
+function runSelectionTests(subject)
 {
   Services.obs.removeObserver(runSelectionTests,
     InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
 
+  is(subject.wrappedJSObject, InspectorUI,
+     "InspectorUI accessible in the observer");
+
   executeSoon(function() {
     Services.obs.addObserver(performTestComparisons,
       InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
     EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
   });
 }
 
 function performTestComparisons(evt)
@@ -112,22 +115,22 @@ function performTestComparisons(evt)
     InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
 
   InspectorUI.stopInspecting();
   ok(InspectorUI.highlighter.isHighlighting, "highlighter is highlighting");
   is(InspectorUI.highlighter.highlitNode, h1, "highlighter matches selection")
   is(InspectorUI.selection, h1, "selection matches node");
   is(InspectorUI.selection, InspectorUI.highlighter.highlitNode, "selection matches highlighter");
 
-  Services.obs.addObserver(finishTestComparisons,
-      InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
 
   div = doc.querySelector("div#checkOutThisWickedSpread");
 
   executeSoon(function() {
+    Services.obs.addObserver(finishTestComparisons,
+        InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
     InspectorUI.inspectNode(div);
   });
 }
 
 function finishTestComparisons()
 {
   Services.obs.removeObserver(finishTestComparisons,
     InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
--- a/browser/devtools/highlighter/test/browser_inspector_iframeTest.js
+++ b/browser/devtools/highlighter/test/browser_inspector_iframeTest.js
@@ -100,23 +100,25 @@ function runIframeTests()
 
   executeSoon(moveMouseOver.bind(this, div1));
 }
 
 function performTestComparisons1()
 {
   Services.obs.removeObserver(performTestComparisons1,
     InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
-  Services.obs.addObserver(performTestComparisons2,
-    InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
 
   is(InspectorUI.selection, div1, "selection matches div1 node");
   is(InspectorUI.highlighter.highlitNode, div1, "highlighter matches selection");
 
-  executeSoon(moveMouseOver.bind(this, div2));
+  executeSoon(function() {
+    Services.obs.addObserver(performTestComparisons2,
+      InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
+    moveMouseOver(div2);
+  });
 }
 
 function performTestComparisons2()
 {
   Services.obs.removeObserver(performTestComparisons2,
     InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
 
   is(InspectorUI.selection, div2, "selection matches div2 node");
--- a/browser/devtools/highlighter/test/browser_inspector_keybindings.js
+++ b/browser/devtools/highlighter/test/browser_inspector_keybindings.js
@@ -39,41 +39,44 @@ function test()
     });
   }
 
   function lockNode()
   {
     Services.obs.removeObserver(lockNode,
       InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
 
-    EventUtils.synthesizeKey("VK_ESCAPE", { });
+    EventUtils.synthesizeKey("VK_RETURN", { });
 
     executeSoon(isTheNodeLocked);
   }
 
   function isTheNodeLocked()
   {
     is(InspectorUI.selection, node, "selection matches node");
     ok(!InspectorUI.inspecting, "the node is locked");
     unlockNode();
   }
 
   function unlockNode() {
-    EventUtils.synthesizeKey("VK_ESCAPE", { });
+    EventUtils.synthesizeKey("VK_RETURN", { });
 
     executeSoon(isTheNodeUnlocked);
   }
 
   function isTheNodeUnlocked()
   {
     ok(InspectorUI.inspecting, "the node is unlocked");
 
+    // Let's close the inspector
     Services.obs.addObserver(finishUp,
       InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
-    InspectorUI.closeInspectorUI();
+
+    EventUtils.synthesizeKey("VK_ESCAPE", {});
+    ok(true, "Inspector is closing successfuly");
   }
 
   function finishUp() {
     Services.obs.removeObserver(finishUp,
                                 InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
     doc = node = null;
     gBrowser.removeCurrentTab();
     finish();
--- a/browser/devtools/shared/Templater.jsm
+++ b/browser/devtools/shared/Templater.jsm
@@ -338,17 +338,17 @@ Templater.prototype._toNode = function(t
  * an inserter function.
  * @param thing The object which could be real data or a promise of real data
  * we use it directly if it's not a promise, or resolve it if it is.
  * @param siblingNode The element before which we insert new elements.
  * @param inserter The function to to the insertion. If thing is not a promise
  * then _handleAsync() is just 'inserter(thing, siblingNode)'
  */
 Templater.prototype._handleAsync = function(thing, siblingNode, inserter) {
-  if (typeof thing.then === 'function') {
+  if (thing != null && typeof thing.then === 'function') {
     // Placeholder element to be replaced once we have the real data
     var tempNode = siblingNode.ownerDocument.createElement('span');
     siblingNode.parentNode.insertBefore(tempNode, siblingNode);
     thing.then(function(delayed) {
       inserter(delayed, tempNode);
       tempNode.parentNode.removeChild(tempNode);
     }.bind(this));
   }
--- a/browser/devtools/webconsole/GcliCommands.jsm
+++ b/browser/devtools/webconsole/GcliCommands.jsm
@@ -79,17 +79,17 @@ gcli.addCommand({
     let commandNames = canon.getCommandNames();
     commandNames.sort();
 
     output.push("<table>");
     for (let i = 0; i < commandNames.length; i++) {
       let command = canon.getCommand(commandNames[i]);
       if (!command.hidden && command.description) {
         output.push("<tr>");
-        output.push('<th class="gcliCmdHelpRight">' + command.name + "</th>");
+        output.push('<th class="gcli-help-right">' + command.name + "</th>");
         output.push("<td>&#x2192; " + command.description + "</td>");
         output.push("</tr>");
       }
     }
     output.push("</table>");
 
     return output.join("");
   }
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -3554,17 +3554,17 @@ HeadsUpDisplay.prototype = {
       if (!usegcli) {
         let context = Cu.getWeakReference(aWindow);
         let mixin = new JSTermFirefoxMixin(context, aParentNode,
                                            aExistingConsole);
         this.jsterm = new JSTerm(context, aParentNode, mixin, this.console);
       }
       else {
         this.gcliterm = new GcliTerm(aWindow, this.hudId, this.chromeDocument,
-                                     this.console, this.hintNode);
+                                     this.console, this.hintNode, this.consoleWrap);
         aParentNode.appendChild(this.gcliterm.element);
       }
     }
     else {
       throw new Error("Unsupported Gecko Application");
     }
   },
 
@@ -3652,31 +3652,29 @@ HeadsUpDisplay.prototype = {
     this.createConsoleMenu(this.consoleWrap);
 
     this.filterPrefs = HUDService.getDefaultFilterPrefs(this.hudId);
 
     let consoleFilterToolbar = this.makeFilterToolbar();
     consoleFilterToolbar.setAttribute("id", "viewGroup");
     this.consoleFilterToolbar = consoleFilterToolbar;
 
-    let hintSpacerNode = this.makeXULNode("box");
-    hintSpacerNode.setAttribute("flex", 1);
-
     this.hintNode = this.makeXULNode("div");
     this.hintNode.setAttribute("class", "gcliterm-hint-node");
 
     let hintParentNode = this.makeXULNode("vbox");
     hintParentNode.setAttribute("flex", "0");
     hintParentNode.setAttribute("class", "gcliterm-hint-parent");
-    hintParentNode.appendChild(hintSpacerNode);
+    hintParentNode.setAttribute("pack", "end");
     hintParentNode.appendChild(this.hintNode);
     hintParentNode.hidden = true;
 
     let hbox = this.makeXULNode("hbox");
     hbox.setAttribute("flex", "1");
+    hbox.setAttribute("class", "gcliterm-display");
 
     this.outputNode = this.makeXULNode("richlistbox");
     this.outputNode.setAttribute("class", "hud-output-node");
     this.outputNode.setAttribute("flex", "1");
     this.outputNode.setAttribute("orient", "vertical");
     this.outputNode.setAttribute("context", this.hudId + "-output-contextmenu");
     this.outputNode.setAttribute("style", "direction: ltr;");
     this.outputNode.setAttribute("seltype", "multiple");
@@ -3759,18 +3757,18 @@ HeadsUpDisplay.prototype = {
         name: "PageJS",
         category: "js",
         severities: [
           { name: "ConsoleErrors", prefKey: "exception" },
           { name: "ConsoleWarnings", prefKey: "jswarn" }
         ]
       },
       {
-        name: "PageWebDeveloper",
-        category: "webdev",
+        name: "PageLogging",
+        category: "logging",
         severities: [
           { name: "ConsoleErrors", prefKey: "error" },
           { name: "ConsoleWarnings", prefKey: "warn" },
           { name: "ConsoleInfo", prefKey: "info" },
           { name: "ConsoleLog", prefKey: "log" }
         ]
       }
     ];
@@ -6946,17 +6944,17 @@ let commandExports = undefined;
  * @param nsIDOMDocument aDocument
  *        The DOM document from which to create nodes.
  * @param object aConsole
  *        Console object to use within the GcliTerm.
  * @param nsIDOMElement aHintNode
  *        The node to which we add GCLI's hints.
  * @constructor
  */
-function GcliTerm(aContentWindow, aHudId, aDocument, aConsole, aHintNode)
+function GcliTerm(aContentWindow, aHudId, aDocument, aConsole, aHintNode, aConsoleWrap)
 {
   this.context = Cu.getWeakReference(aContentWindow);
   this.hudId = aHudId;
   this.document = aDocument;
   this.console = aConsole;
   this.hintNode = aHintNode;
 
   this.createUI();
@@ -6972,17 +6970,17 @@ function GcliTerm(aContentWindow, aHudId
     jsEnvironment: {
       globalObject: unwrap(aContentWindow),
       evalFunction: this.evalInSandbox.bind(this)
     },
     inputElement: this.inputNode,
     completeElement: this.completeNode,
     inputBackgroundElement: this.inputStack,
     hintElement: this.hintNode,
-    completionPrompt: "",
+    consoleWrap: aConsoleWrap,
     gcliTerm: this
   };
 
   gcli._internal.commandOutputManager.addListener(this.onCommandOutput, this);
   gcli._internal.createView(this.opts);
 
   if (!commandExports) {
     commandExports = loadCommands();
@@ -6990,17 +6988,25 @@ function GcliTerm(aContentWindow, aHudId
 }
 
 GcliTerm.prototype = {
   /**
    * Remove the hint column from the display.
    */
   hide: function GcliTerm_hide()
   {
-    this.hintNode.parentNode.hidden = true;
+    let permaHint = false;
+    try {
+      permaHint = Services.prefs.getBoolPref("devtools.gcli.permaHint");
+    }
+    catch (ex) {}
+
+    if (!permaHint) {
+      this.hintNode.parentNode.hidden = true;
+    }
   },
 
   /**
    * Undo the effects of calling hide().
    */
   show: function GcliTerm_show()
   {
     this.hintNode.parentNode.hidden = false;
--- a/browser/devtools/webconsole/gcli.jsm
+++ b/browser/devtools/webconsole/gcli.jsm
@@ -233,17 +233,21 @@ var console = {};
       }
       catch (ex) {
         // Can't use a real ellipsis here, because cmd.exe isn't unicode-enabled
         json = "{" + Object.keys(aThing).join(":..,") + ":.., " + "}";
       }
       return type + fmt(json, 50, 0);
     }
 
-    var str = aThing.toString(); //.replace(/\s+/g, " ");
+    if (typeof aThing == "function") {
+      return fmt(aThing.toString().replace(/\s+/g, " "), 80, 0);
+    }
+
+    var str = aThing.toString().replace(/\n/g, "|");
     return fmt(str, 80, 0);
   }
 
   /**
    * Create a simple debug representation of a given element.
    *
    * @param {nsIDOMElement} aElement
    *        The element to debug
@@ -290,20 +294,33 @@ var console = {};
         var keys = Object.getOwnPropertyNames(aThing);
         if (keys.length > 0) {
           reply += type + "\n";
           keys.forEach(function(aProp) {
             reply += logProperty(aProp, aThing[aProp]);
           }, this);
         }
         else {
-          reply += type + " (enumerated with for-in)\n";
-          var prop;
-          for (prop in aThing) {
-            reply += logProperty(prop, aThing[prop]);
+          reply += type + "\n";
+          var root = aThing;
+          var logged = [];
+          while (root != null) {
+            var properties = Object.keys(root);
+            properties.sort();
+            properties.forEach(function(property) {
+              if (!(property in logged)) {
+                logged[property] = property;
+                reply += logProperty(property, aThing[property]);
+              }
+            });
+
+            root = Object.getPrototypeOf(root);
+            if (root != null) {
+              reply += '  - prototype ' + getCtorName(root) + '\n';
+            }
           }
         }
       }
 
       return reply;
     }
 
     return "  " + aThing.toString() + "\n";
@@ -664,37 +681,34 @@ var mozl10n = {};
     }
     catch (ex) {
       throw new Error("Failure in lookupFormat('" + name + "')");
     }
   };
 
 })(mozl10n);
 
-define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types/basic', 'gcli/types/javascript', 'gcli/types/node', 'gcli/cli', 'gcli/ui/inputter', 'gcli/ui/arg_fetch', 'gcli/ui/menu', 'gcli/ui/focus'], function(require, exports, module) {
+define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types/basic', 'gcli/types/javascript', 'gcli/types/node', 'gcli/cli', 'gcli/ui/display'], function(require, exports, module) {
 
   // The API for use by command authors
   exports.addCommand = require('gcli/canon').addCommand;
   exports.removeCommand = require('gcli/canon').removeCommand;
   exports.lookup = mozl10n.lookup;
   exports.lookupFormat = mozl10n.lookupFormat;
 
   // Internal startup process. Not exported
   require('gcli/types/basic').startup();
   require('gcli/types/javascript').startup();
   require('gcli/types/node').startup();
   require('gcli/cli').startup();
 
   var Requisition = require('gcli/cli').Requisition;
+  var Display = require('gcli/ui/display').Display;
+
   var cli = require('gcli/cli');
-  var Inputter = require('gcli/ui/inputter').Inputter;
-  var ArgFetcher = require('gcli/ui/arg_fetch').ArgFetcher;
-  var CommandMenu = require('gcli/ui/menu').CommandMenu;
-  var FocusManager = require('gcli/ui/focus').FocusManager;
-
   var jstype = require('gcli/types/javascript');
   var nodetype = require('gcli/types/node');
 
   /**
    * API for use by HUDService only.
    * This code is internal and subject to change without notice.
    */
   exports._internal = {
@@ -712,69 +726,40 @@ define('gcli/index', ['require', 'export
      * - jsEnvironment.evalFunction: 'eval' in a sandbox
      * - inputElement: GCLITerm.inputNode
      * - completeElement: GCLITerm.completeNode
      * - gcliTerm: GCLITerm
      * - hintElement: GCLITerm.hintNode
      * - inputBackgroundElement: GCLITerm.inputStack
      */
     createView: function(opts) {
-      opts.autoHide = true;
-      opts.requisition = new Requisition(opts.environment, opts.chromeDocument);
-      opts.completionPrompt = '';
-
       jstype.setGlobalObject(opts.jsEnvironment.globalObject);
       nodetype.setDocument(opts.contentDocument);
       cli.setEvalFunction(opts.jsEnvironment.evalFunction);
 
-      // Create a FocusManager for the various parts to register with
-      if (!opts.focusManager) {
-        opts.debug = true;
-        opts.focusManager = new FocusManager({ document: opts.chromeDocument });
+      if (opts.requisition == null) {
+        opts.requisition = new Requisition(opts.environment, opts.chromeDocument);
       }
 
-      opts.inputter = new Inputter(opts);
-      opts.inputter.update();
-      if (opts.gcliTerm) {
-        opts.focusManager.onFocus.add(opts.gcliTerm.show, opts.gcliTerm);
-        opts.focusManager.onBlur.add(opts.gcliTerm.hide, opts.gcliTerm);
-        opts.focusManager.addMonitoredElement(opts.gcliTerm.hintNode, 'gcliTerm');
-      }
-
-      if (opts.hintElement) {
-        opts.menu = new CommandMenu(opts.chromeDocument, opts.requisition);
-        opts.hintElement.appendChild(opts.menu.element);
-
-        opts.argFetcher = new ArgFetcher(opts.chromeDocument, opts.requisition);
-        opts.hintElement.appendChild(opts.argFetcher.element);
-
-        opts.menu.onCommandChange();
-      }
+      opts.display = new Display(opts);
     },
 
     /**
      * Undo the effects of createView() to prevent memory leaks
      */
     removeView: function(opts) {
-      opts.hintElement.removeChild(opts.menu.element);
-      opts.menu.destroy();
-      opts.hintElement.removeChild(opts.argFetcher.element);
-      opts.argFetcher.destroy();
-
-      opts.inputter.destroy();
-      opts.focusManager.removeMonitoredElement(opts.gcliTerm.hintNode, 'gcliTerm');
-      opts.focusManager.onFocus.remove(opts.gcliTerm.show, opts.gcliTerm);
-      opts.focusManager.onBlur.remove(opts.gcliTerm.hide, opts.gcliTerm);
-      opts.focusManager.destroy();
+      opts.display.destroy();
+      delete opts.display;
+
+      opts.requisition.destroy();
+      delete opts.requisition;
 
       cli.unsetEvalFunction();
       nodetype.unsetDocument();
       jstype.unsetGlobalObject();
-
-      opts.requisition.destroy();
     },
 
     commandOutputManager: require('gcli/canon').commandOutputManager
   };
 });
 /*
  * Copyright 2009-2011 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.txt or:
@@ -1121,24 +1106,17 @@ canon.commandOutputManager = new Command
  * Copyright 2009-2011 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.txt or:
  * http://opensource.org/licenses/BSD-3-Clause
  */
 
 define('gcli/util', ['require', 'exports', 'module' ], function(require, exports, module) {
 
 /*
- * This module is a Pilot-Lite. It exports a number of objects that replicate
- * parts of the Pilot project. It aims to be mostly API compatible, while
- * removing the submodule complexity and helping us make things work inside
- * Firefox.
- * The Pilot compatible exports are: console/dom/event
- *
- * In addition it contains a small event library similar to EventEmitter but
- * which makes it harder to mistake the event in use.
+ * A number of DOM manipulation and event handling utilities.
  */
 
 
 //------------------------------------------------------------------------------
 
 /**
  * Create an event.
  * For use as follows:
@@ -1207,36 +1185,35 @@ exports.createEvent = function(name) {
   return event;
 };
 
 
 //------------------------------------------------------------------------------
 
 var dom = {};
 
-var NS_XHTML = 'http://www.w3.org/1999/xhtml';
-
-/**
- * Pass-through to createElement or createElementNS
+dom.NS_XHTML = 'http://www.w3.org/1999/xhtml';
+
+/**
+ * Create an HTML or XHTML element depending on whether the document is HTML
+ * or XML based. Where HTML/XHTML elements are distinguished by whether they
+ * are created using doc.createElementNS('http://www.w3.org/1999/xhtml', tag)
+ * or doc.createElement(tag)
+ * If you want to create a XUL element then you don't have a problem knowing
+ * what namespace you want.
  * @param doc The document in which to create the element
  * @param tag The name of the tag to create
- * @param ns Custom namespace, HTML/XHTML is assumed if this is missing
  * @returns The created element
  */
-dom.createElement = function(doc, tag, ns) {
-  // If we've not been given a namespace, but the document is XML, then we
-  // use an XHTML namespace, otherwise we use HTML
-  if (ns == null && doc.xmlVersion != null) {
-    ns = NS_XHTML;
-  }
-  if (ns == null) {
-    return doc.createElement(tag);
+dom.createElement = function(doc, tag) {
+  if (dom.isXmlDocument(doc)) {
+    return doc.createElementNS(dom.NS_XHTML, tag);
   }
   else {
-    return doc.createElementNS(ns, tag);
+    return doc.createElement(tag);
   }
 };
 
 /**
  * Remove all the child nodes from this node
  * @param elem The element that should have it's children removed
  */
 dom.clearElement = function(elem) {
@@ -1259,36 +1236,55 @@ dom.importCss = function(cssText, doc) {
 
   var head = doc.getElementsByTagName('head')[0] || doc.documentElement;
   head.appendChild(style);
 
   return style;
 };
 
 /**
- * Using setInnerHtml(foo) rather than innerHTML = foo allows us to enable
- * tweaks in XHTML documents.
+ * There are problems with innerHTML on XML documents, so we need to do a dance
+ * using document.createRange().createContextualFragment() when in XML mode
  */
 dom.setInnerHtml = function(elem, html) {
-  if (!this.document || elem.namespaceURI === NS_XHTML) {
-    try {
-      dom.clearElement(elem);
-      var range = elem.ownerDocument.createRange();
-      html = '<div xmlns="' + NS_XHTML + '">' + html + '</div>';
-      elem.appendChild(range.createContextualFragment(html));
-    }
-    catch (ex) {
-      elem.innerHTML = html;
+  if (dom.isXmlDocument(elem.ownerDocument)) {
+    dom.clearElement(elem);
+    html = '<div xmlns="' + dom.NS_XHTML + '">' + html + '</div>';
+    var range = elem.ownerDocument.createRange();
+    var child = range.createContextualFragment(html).childNodes[0];
+    while (child.hasChildNodes()) {
+      elem.appendChild(child.firstChild);
     }
   }
   else {
     elem.innerHTML = html;
   }
 };
 
+/**
+ * How to detect if we're in an XUL document (and therefore should create
+ * elements in an XHTML namespace)
+ * In a Mozilla XUL document, document.xmlVersion = null, however in Chrome
+ * document.contentType = undefined.
+ * @param doc The document element to work from (defaulted to the global
+ * 'document' if missing
+ */
+dom.isXmlDocument = function(doc) {
+  doc = doc || document;
+  // Best test for Firefox
+  if (doc.contentType && doc.contentType != 'text/html') {
+    return true;
+  }
+  // Best test for Chrome
+  if (doc.xmlVersion != null) {
+    return true;
+  }
+  return false;
+};
+
 exports.dom = dom;
 
 
 //------------------------------------------------------------------------------
 
 /**
  * Various event utilities
  */
@@ -4032,24 +4028,26 @@ UnassignedAssignment.prototype.setUnassi
  * The event object looks like { command: A }
  * <li>assignmentChange: This is a forward of the Assignment.assignmentChange
  * event. It is fired when any assignment (except the commandAssignment)
  * changes.
  * <li>inputChange: The text to be mirrored in a command line has changed.
  * The event object looks like { newText: X }.
  * </ul>
  *
- * @param environment An opaque object passed to commands using ExecutionContext
- * @param document A DOM Document passed to commands using ExecutionContext in
- * order to allow creation of DOM nodes.
+ * @param environment An optional opaque object passed to commands using
+ * ExecutionContext.
+ * @param doc A DOM Document passed to commands using ExecutionContext in
+ * order to allow creation of DOM nodes. If missing Requisition will use the
+ * global 'document'.
  * @constructor
  */
-function Requisition(environment, document) {
+function Requisition(environment, doc) {
   this.environment = environment;
-  this.document = document;
+  this.document = doc || document;
 
   // The command that we are about to execute.
   // @see setCommandConversion()
   this.commandAssignment = new CommandAssignment();
 
   // The object that stores of Assignment objects that we are filling out.
   // The Assignment objects are stored under their param.name for named
   // lookup. Note: We make use of the property of Javascript objects that
@@ -4181,17 +4179,16 @@ Requisition.prototype._onCommandAssignme
   }
   this.assignmentCount = Object.keys(this._assignments).length;
 
   this.commandChange({
     requisition: this,
     oldValue: ev.oldValue,
     newValue: command
   });
-//  this.inputChange();
 };
 
 /**
  * Assignments have an order, so we need to store them in an array.
  * But we also need named access ...
  * @return The found assignment, or undefined, if no match was found
  */
 Requisition.prototype.getAssignment = function(nameOrNumber) {
@@ -4366,26 +4363,24 @@ Requisition.prototype.toString = functio
   }
 
   return this.toCanonicalString();
 };
 
 /**
  * Return an array of Status scores so we can create a marked up
  * version of the command line input.
- */
-Requisition.prototype.getInputStatusMarkup = function() {
+ * @param cursor We only take a status of INCOMPLETE to be INCOMPLETE when the
+ * cursor is actually in the argument. Otherwise it's an error.
+ */
+Requisition.prototype.getInputStatusMarkup = function(cursor) {
   var argTraces = this.createInputArgTrace();
-  // We only take a status of INCOMPLETE to be INCOMPLETE when the cursor is
-  // actually in the argument. Otherwise it's an error.
   // Generally the 'argument at the cursor' is the argument before the cursor
   // unless it is before the first char, in which case we take the first.
-  var cursor = this.input.cursor.start === 0 ?
-      0 :
-      this.input.cursor.start - 1;
+  cursor = cursor === 0 ? 0 : cursor - 1;
   var cTrace = argTraces[cursor];
 
   var statuses = [];
   for (var i = 0; i < argTraces.length; i++) {
     var argTrace = argTraces[i];
     var arg = argTrace.arg;
     var status = Status.VALID;
     if (argTrace.part === 'text') {
@@ -4564,19 +4559,18 @@ Requisition.prototype.exec = function(in
  * <p>The general sequence is:
  * <ul>
  * <li>_tokenize(): convert _typed into _parts
  * <li>_split(): convert _parts into _command and _unparsedArgs
  * <li>_assign(): convert _unparsedArgs into requisition
  * </ul>
  */
 Requisition.prototype.update = function(input) {
-  this.input = input;
-  if (this.input.cursor == null) {
-    this.input.cursor = { start: input.length, end: input.length };
+  if (input.cursor == null) {
+    input.cursor = { start: input.length, end: input.length };
   }
 
   this._structuralChangeInProgress = true;
 
   this._args = this._tokenize(input.typed);
 
   var args = this._args.slice(0); // i.e. clone
   this._split(args);
@@ -5042,16 +5036,145 @@ define('gcli/promise', ['require', 'expo
 
 });
 /*
  * Copyright 2009-2011 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.txt or:
  * http://opensource.org/licenses/BSD-3-Clause
  */
 
+define('gcli/ui/display', ['require', 'exports', 'module' , 'gcli/ui/inputter', 'gcli/ui/arg_fetch', 'gcli/ui/menu', 'gcli/ui/focus'], function(require, exports, module) {
+
+var Inputter = require('gcli/ui/inputter').Inputter;
+var ArgFetcher = require('gcli/ui/arg_fetch').ArgFetcher;
+var CommandMenu = require('gcli/ui/menu').CommandMenu;
+var FocusManager = require('gcli/ui/focus').FocusManager;
+
+/**
+ * Display is responsible for generating the UI for GCLI, this implementation
+ * is a special case for use inside Firefox
+ */
+function Display(options) {
+  this.hintElement = options.hintElement;
+  this.gcliTerm = options.gcliTerm;
+  this.consoleWrap = options.consoleWrap;
+  this.requisition = options.requisition;
+
+  // Create a FocusManager for the various parts to register with
+  this.focusManager = new FocusManager({ document: options.chromeDocument });
+  this.focusManager.onFocus.add(this.gcliTerm.show, this.gcliTerm);
+  this.focusManager.onBlur.add(this.gcliTerm.hide, this.gcliTerm);
+  this.focusManager.addMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');
+
+  this.inputter = new Inputter({
+    document: options.contentDocument,
+    requisition: options.requisition,
+    inputElement: options.inputElement,
+    completeElement: options.completeElement,
+    completionPrompt: '',
+    backgroundElement: options.backgroundElement,
+    focusManager: this.focusManager
+  });
+
+  this.menu = new CommandMenu({
+    document: options.contentDocument,
+    requisition: options.requisition,
+    menuClass: 'gcliterm-menu'
+  });
+  this.hintElement.appendChild(this.menu.element);
+
+  this.argFetcher = new ArgFetcher({
+    document: options.contentDocument,
+    requisition: options.requisition,
+    argFetcherClass: 'gcliterm-argfetcher'
+  });
+  this.hintElement.appendChild(this.argFetcher.element);
+
+  this.chromeWindow = options.chromeDocument.defaultView;
+  this.resizer = this.resizer.bind(this);
+  this.chromeWindow.addEventListener('resize', this.resizer, false);
+  this.requisition.commandChange.add(this.resizer, this);
+}
+
+/**
+ * Avoid memory leaks
+ */
+Display.prototype.destroy = function() {
+  this.chromeWindow.removeEventListener('resize', this.resizer, false);
+  delete this.resizer;
+  delete this.chromeWindow;
+  delete this.consoleWrap;
+
+  this.hintElement.removeChild(this.menu.element);
+  this.menu.destroy();
+  this.hintElement.removeChild(this.argFetcher.element);
+  this.argFetcher.destroy();
+
+  this.inputter.destroy();
+
+  this.focusManager.removeMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');
+  this.focusManager.onFocus.remove(this.gcliTerm.show, this.gcliTerm);
+  this.focusManager.onBlur.remove(this.gcliTerm.hide, this.gcliTerm);
+  this.focusManager.destroy();
+
+  delete this.gcliTerm;
+  delete this.hintElement;
+};
+
+/**
+ * Called on chrome window resize, or on divider slide
+ */
+Display.prototype.resizer = function() {
+  var parentRect = this.consoleWrap.getBoundingClientRect();
+  var parentHeight = parentRect.bottom - parentRect.top - 64;
+
+  if (parentHeight < 100) {
+    this.hintElement.classList.add('gcliterm-hint-nospace');
+  }
+  else {
+    this.hintElement.classList.remove('gcliterm-hint-nospace');
+
+    var isMenuVisible = this.menu.element.style.display !== 'none';
+    if (isMenuVisible) {
+      this.menu.setMaxHeight(parentHeight);
+
+      // Magic numbers. We have 2 options - lots of complex dom math to derive
+      // the height of a menu item (19 pixels) and the vertical padding
+      // (22 pixels), or we could just hard-code. The former is *slightly* more
+      // resilient to refactoring (but still breaks with dom structure changes),
+      // the latter is simpler, faster and easier.
+      var idealMenuHeight = (19 * this.menu.items.length) + 22;
+
+      if (idealMenuHeight > parentHeight) {
+        this.hintElement.style.overflowY = 'scroll';
+        this.hintElement.style.borderBottomColor = 'threedshadow';
+      }
+      else {
+        this.hintElement.style.overflowY = null;
+        this.hintElement.style.borderBottomColor = 'white';
+      }
+    }
+    else {
+      this.argFetcher.setMaxHeight(parentHeight);
+
+      this.hintElement.style.overflowY = null;
+      this.hintElement.style.borderBottomColor = 'white';
+    }
+  }
+};
+
+exports.Display = Display;
+
+});
+/*
+ * Copyright 2009-2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE.txt or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+
 define('gcli/ui/inputter', ['require', 'exports', 'module' , 'gcli/util', 'gcli/types', 'gcli/history', 'text!gcli/ui/inputter.css'], function(require, exports, module) {
 var cliView = exports;
 
 
 var KeyEvent = require('gcli/util').event.KeyEvent;
 var dom = require('gcli/util').dom;
 
 var Status = require('gcli/types').Status;
@@ -5062,17 +5185,17 @@ var inputterCss = require('text!gcli/ui/
 
 /**
  * A wrapper to take care of the functions concerning an input element
  */
 function Inputter(options) {
   this.requisition = options.requisition;
 
   // Suss out where the input element is
-  this.element = options.inputElement || 'gcliInput';
+  this.element = options.inputElement || 'gcli-input';
   if (typeof this.element === 'string') {
     this.document = options.document || document;
     var name = this.element;
     this.element = this.document.getElementById(name);
     if (!this.element) {
       throw new Error('No element with id=' + name + '.');
     }
   }
@@ -5094,41 +5217,37 @@ function Inputter(options) {
   this._caretChange = null;
 
   // Ensure that TAB/UP/DOWN isn't handled by the browser
   this.onKeyDown = this.onKeyDown.bind(this);
   this.onKeyUp = this.onKeyUp.bind(this);
   this.element.addEventListener('keydown', this.onKeyDown, false);
   this.element.addEventListener('keyup', this.onKeyUp, false);
 
-  if (options.completer == null) {
-    options.completer = new Completer(options);
-  }
-  else if (typeof options.completer === 'function') {
-    options.completer = new options.completer(options);
-  }
-  this.completer = options.completer;
+  this.completer = options.completer || new Completer(options);
   this.completer.decorate(this);
 
   // Use the provided history object, or instantiate our own
-  this.history = options.history = options.history || new History(options);
+  this.history = options.history || new History(options);
   this._scrollingThroughHistory = false;
 
   // Cursor position affects hint severity
   this.onMouseUp = function(ev) {
     this.completer.update(this.getInputState());
   }.bind(this);
   this.element.addEventListener('mouseup', this.onMouseUp, false);
 
   this.focusManager = options.focusManager;
   if (this.focusManager) {
     this.focusManager.addMonitoredElement(this.element, 'input');
   }
 
   this.requisition.inputChange.add(this.onInputChange, this);
+
+  this.update();
 }
 
 /**
  * Avoid memory leaks
  */
 Inputter.prototype.destroy = function() {
   this.requisition.inputChange.remove(this.onInputChange, this);
   if (this.focusManager) {
@@ -5367,22 +5486,22 @@ Inputter.prototype.onKeyUp = function(ev
   if (ev.keyCode === KeyEvent.DOM_VK_TAB && !ev.shiftKey) {
     // If the TAB keypress took the cursor from another field to this one,
     // then they get the keydown/keypress, and we get the keyup. In this
     // case we don't want to do any completion.
     // If the time of the keydown/keypress of TAB was close (i.e. within
     // 1 second) to the time of the keyup then we assume that we got them
     // both, and do the completion.
     if (this.lastTabDownAt + 1000 > ev.timeStamp) {
-      this.getCurrentAssignment().complete();
       // It's possible for TAB to not change the input, in which case the
       // onInputChange event will not fire, and the caret move will not be
-      // processed. So we check that this is done
+      // processed. So we check that this is done first
       this._caretChange = Caret.TO_ARG_END;
       this._processCaretChange(this.getInputState(), true);
+      this.getCurrentAssignment().complete();
     }
     this.lastTabDownAt = 0;
     this._scrollingThroughHistory = false;
     return;
   }
 
   if (ev.keyCode === KeyEvent.DOM_VK_UP) {
     if (this.element.value === '' || this._scrollingThroughHistory) {
@@ -5462,37 +5581,37 @@ cliView.Inputter = Inputter;
  * Properties on the options object:
  * - document (required) DOM document to be used in creating elements
  * - requisition (required) A GCLI Requisition object whose state is monitored
  * - completeElement (optional) An element to use
  * - completionPrompt (optional) The prompt to show before a completion.
  *   Defaults to '&#x00bb;' (double greater-than, a.k.a right guillemet).
  */
 function Completer(options) {
-  this.document = options.document;
+  this.document = options.document || document;
   this.requisition = options.requisition;
   this.elementCreated = false;
 
-  this.element = options.completeElement || 'gcliComplete';
+  this.element = options.completeElement || 'gcli-row-complete';
   if (typeof this.element === 'string') {
     var name = this.element;
     this.element = this.document.getElementById(name);
 
     if (!this.element) {
       this.elementCreated = true;
       this.element = dom.createElement(this.document, 'div');
-      this.element.className = 'gcliCompletion gcliVALID';
+      this.element.className = 'gcli-in-complete gcli-in-valid';
       this.element.setAttribute('tabindex', '-1');
       this.element.setAttribute('aria-live', 'polite');
     }
   }
 
   this.completionPrompt = typeof options.completionPrompt === 'string'
-    ? options.completionPrompt
-    : '&#x00bb;';
+      ? options.completionPrompt
+      : '&#x00bb;';
 
   if (options.inputBackgroundElement) {
     this.backgroundElement = options.inputBackgroundElement;
   }
   else {
     this.backgroundElement = this.element;
   }
 }
@@ -5590,47 +5709,47 @@ function isStrictCompletion(inputValue, 
 
 /**
  * Bring the completion element up to date with what the requisition says
  */
 Completer.prototype.update = function(input) {
   var current = this.requisition.getAssignmentAt(input.cursor.start);
   var predictions = current.getPredictions();
 
-  var completion = '<span class="gcliPrompt">' + this.completionPrompt + '</span> ';
+  var completion = '<span class="gcli-prompt">' + this.completionPrompt + '</span> ';
   if (input.typed.length > 0) {
-    var scores = this.requisition.getInputStatusMarkup();
+    var scores = this.requisition.getInputStatusMarkup(input.cursor.start);
     completion += this.markupStatusScore(scores, input);
   }
 
   if (input.typed.length > 0 && predictions.length > 0) {
     var tab = predictions[0].name;
     var existing = current.getArg().text;
     if (isStrictCompletion(existing, tab) && input.cursor.start === input.typed.length) {
       // Display the suffix of the prediction as the completion.
       var numLeadingSpaces = existing.match(/^(\s*)/)[0].length;
       var suffix = tab.slice(existing.length - numLeadingSpaces);
-      completion += '<span class="gcliCompl">' + suffix + '</span>';
+      completion += '<span class="gcli-in-ontab">' + suffix + '</span>';
     } else {
       // Display the '-> prediction' at the end of the completer element
-      completion += ' &#xa0;<span class="gcliCompl">&#x21E5; ' +
+      completion += ' &#xa0;<span class="gcli-in-ontab">&#x21E5; ' +
           tab + '</span>';
     }
   }
 
   // A hack to add a grey '}' to the end of the command line when we've opened
   // with a { but haven't closed it
   var command = this.requisition.commandAssignment.getValue();
   if (command && command.name === '{') {
     if (this.requisition.getAssignment(0).getArg().suffix.indexOf('}') === -1) {
-      completion += '<span class="gcliCloseBrace">}</span>';
-    }
-  }
-
-  dom.setInnerHtml(this.element, '<span>' + completion + '</span>');
+      completion += '<span class="gcli-in-closebrace">}</span>';
+    }
+  }
+
+  dom.setInnerHtml(this.element, completion);
 };
 
 /**
  * Mark-up an array of Status values with spans
  */
 Completer.prototype.markupStatusScore = function(scores, input) {
   var completion = '';
   if (scores.length === 0) {
@@ -5641,17 +5760,17 @@ Completer.prototype.markupStatusScore = 
   var lastStatus = -1;
   while (true) {
     if (lastStatus !== scores[i]) {
       var state = scores[i];
       if (!state) {
         console.error('No state at i=' + i + '. scores.len=' + scores.length);
         state = Status.VALID;
       }
-      completion += '<span class="gcli' + state.toString() + '">';
+      completion += '<span class="gcli-in-' + state.toString().toLowerCase() + '">';
       lastStatus = scores[i];
     }
     var char = input.typed[i];
     if (char === ' ') {
       char = '&#xa0;';
     }
     completion += char;
     i++;
@@ -5752,48 +5871,53 @@ var Templater = require('gcli/ui/domtemp
 
 var editorCss = require('text!gcli/ui/arg_fetch.css');
 var argFetchHtml = require('text!gcli/ui/arg_fetch.html');
 
 
 /**
  * A widget to display an inline dialog which allows the user to fill out
  * the arguments to a command.
- * @param document The document to use in creating widgets
- * @param requisition The Requisition to fill out
- */
-function ArgFetcher(document, requisition) {
-  this.document = document;
-  this.requisition = requisition;
+ * @param options An object containing the customizations, which include:
+ * - document: The document to use in creating widgets
+ * - requisition: The Requisition to fill out
+ * - argFetcherClass: Custom class name when generating the top level element
+ *   which allows different layout systems
+ */
+function ArgFetcher(options) {
+  this.document = options.document || document;
+  this.requisition = options.requisition;
 
   // FF can be really hard to debug if doc is null, so we check early on
   if (!this.document) {
     throw new Error('No document');
   }
 
   this.element =  dom.createElement(this.document, 'div');
-  this.element.className = 'gcliCliEle';
+  this.element.className = options.argFetcherClass || 'gcli-argfetch';
   // We cache the fields we create so we can destroy them later
   this.fields = [];
 
   this.tmpl = new Templater();
   // Populated by template
   this.okElement = null;
 
   // Pull the HTML into the DOM, but don't add it to the document
   if (editorCss != null) {
     this.style = dom.importCss(editorCss, this.document);
   }
 
   var templates = dom.createElement(this.document, 'div');
   dom.setInnerHtml(templates, argFetchHtml);
-  this.reqTempl = templates.querySelector('#gcliReqTempl');
+  this.reqTempl = templates.querySelector('.gcli-af-template');
 
   this.requisition.commandChange.add(this.onCommandChange, this);
   this.requisition.inputChange.add(this.onInputChange, this);
+
+  this.onCommandChange();
 }
 
 /**
  * Avoid memory leaks
  */
 ArgFetcher.prototype.destroy = function() {
   this.requisition.inputChange.remove(this.onInputChange, this);
   this.requisition.commandChange.remove(this.onCommandChange, this);
@@ -5851,41 +5975,49 @@ ArgFetcher.prototype.onInputChange = fun
   }
 };
 
 /**
  * Called by the template process in #onCommandChange() to get an instance
  * of field for each assignment.
  */
 ArgFetcher.prototype.getInputFor = function(assignment) {
-  var newField = getField(assignment.param.type, {
-    document: this.document,
-    type: assignment.param.type,
-    name: assignment.param.name,
-    requisition: this.requisition,
-    required: assignment.param.isDataRequired(),
-    named: !assignment.param.isPositionalAllowed()
-  });
-
-  // BUG 664198 - remove on delete
-  newField.fieldChanged.add(function(ev) {
-    assignment.setConversion(ev.conversion);
-  }, this);
-  assignment.assignmentChange.add(function(ev) {
-    newField.setConversion(ev.conversion);
-  }.bind(this));
-
-  this.fields.push(newField);
-  newField.setConversion(this.assignment.conversion);
-
-  // Bug 681894: we add the field as a property of the assignment so that
-  // #linkMessageElement() can call 'field.setMessageElement(element)'
-  assignment.field = newField;
-
-  return newField.element;
+  try {
+    var newField = getField(assignment.param.type, {
+      document: this.document,
+      type: assignment.param.type,
+      name: assignment.param.name,
+      requisition: this.requisition,
+      required: assignment.param.isDataRequired(),
+      named: !assignment.param.isPositionalAllowed()
+    });
+
+    // BUG 664198 - remove on delete
+    newField.fieldChanged.add(function(ev) {
+      assignment.setConversion(ev.conversion);
+    }, this);
+    assignment.assignmentChange.add(function(ev) {
+      newField.setConversion(ev.conversion);
+    }.bind(this));
+
+    this.fields.push(newField);
+    newField.setConversion(this.assignment.conversion);
+
+    // Bug 681894: we add the field as a property of the assignment so that
+    // #linkMessageElement() can call 'field.setMessageElement(element)'
+    assignment.field = newField;
+
+    return newField.element;
+  }
+  catch (ex) {
+    // This is called from within Templater which can make tracing errors hard
+    // so we log here if anything goes wrong
+    console.error(ex);
+    return '';
+  }
 };
 
 /**
  * Called by the template to setup an mutable message field
  */
 ArgFetcher.prototype.linkMessageElement = function(assignment, element) {
   // Bug 681894: See comment in getInputFor()
   var field = assignment.field;
@@ -5907,16 +6039,32 @@ ArgFetcher.prototype.onFormOk = function
 
 /**
  * Event handler added by the template menu.html
  */
 ArgFetcher.prototype.onFormCancel = function(ev) {
   this.requisition.clear();
 };
 
+/**
+ * Change how much vertical space this dialog can take up
+ */
+ArgFetcher.prototype.setMaxHeight = function(height, isTooBig) {
+  this.fields.forEach(function(field) {
+    if (field.menu) {
+      // Magic number alert: 105 is roughly the size taken up by the rest of
+      // the dialog for the '{' command. We could spend ages calculating 105
+      // by doing math on the various components that contribute to the 105,
+      // but I don't think that would make it significantly less fragile under
+      // refactoring. Plus this works.
+      field.menu.setMaxHeight(height - 105);
+    }
+  });
+};
+
 argFetch.ArgFetcher = ArgFetcher;
 
 
 });
 /*
  * Copyright 2009-2011 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.txt or:
  * http://opensource.org/licenses/BSD-3-Clause
@@ -6099,17 +6247,17 @@ exports.getField = getField;
  */
 function StringField(type, options) {
   this.document = options.document;
   this.type = type;
   this.arg = new Argument();
 
   this.element = dom.createElement(this.document, 'input');
   this.element.type = 'text';
-  this.element.style.width = '100%';
+  this.element.className = 'gcli-field';
 
   this.onInputChange = this.onInputChange.bind(this);
   this.element.addEventListener('keyup', this.onInputChange, false);
 
   this.fieldChanged = createEvent('StringField.fieldChanged');
 }
 
 StringField.prototype = Object.create(Field.prototype);
@@ -6259,17 +6407,17 @@ addField(BooleanField);
  * </ul>
  */
 function SelectionField(type, options) {
   this.document = options.document;
   this.type = type;
   this.items = [];
 
   this.element = dom.createElement(this.document, 'select');
-  this.element.style.width = '180px';
+  this.element.className = 'gcli-field';
   this._addOption({
     name: l10n.lookupFormat('fieldSelectionSelect', [ options.name ])
   });
   var lookup = this.type.getLookup();
   lookup.forEach(this._addOption, this);
 
   this.onInputChange = this.onInputChange.bind(this);
   this.element.addEventListener('change', this.onInputChange, false);
@@ -6334,21 +6482,21 @@ function JavascriptField(type, options) 
   this.onInputChange = this.onInputChange.bind(this);
   this.arg = new Argument('', '{ ', ' }');
 
   this.element = dom.createElement(this.document, 'div');
 
   this.input = dom.createElement(this.document, 'input');
   this.input.type = 'text';
   this.input.addEventListener('keyup', this.onInputChange, false);
-  this.input.style.marginBottom = '0px';
-  this.input.style.width = options.name.length === 0 ? '240px' : '160px';
+  this.input.style.marginBottom = '0';
+  this.input.className = 'gcli-field';
   this.element.appendChild(this.input);
 
-  this.menu = new Menu(this.document, { field: true });
+  this.menu = new Menu({ document: this.document, field: true });
   this.element.appendChild(this.menu.element);
 
   this.setConversion(this.type.parse(new Argument('')));
 
   this.fieldChanged = createEvent('JavascriptField.fieldChanged');
 
   // i.e. Register this.onItemClick as the default action for a menu click
   this.menu.onItemClick = this.onItemClick.bind(this);
@@ -6650,36 +6798,46 @@ var Templater = require('gcli/ui/domtemp
 
 var menuCss = require('text!gcli/ui/menu.css');
 var menuHtml = require('text!gcli/ui/menu.html');
 
 
 /**
  * Menu is a display of the commands that are possible given the state of a
  * requisition.
- * @param document The document from which we create elements.
  * @param options A way to customize the menu display. Valid options are:
- * - field:true Turns the menu display into a drop-down for use inside a
- * JavascriptField.
- */
-function Menu(document, options) {
-  this.element =  dom.createElement(document, 'div');
-  this.element.className = 'gcliMenu';
+ * - field: [boolean] Turns the menu display into a drop-down for use inside a
+ *   JavascriptField.
+ * - document: The document to use in creating widgets
+ * - menuClass: Custom class name when generating the top level element
+ *   which allows different layout systems
+ */
+function Menu(options) {
+  options = options || {};
+  this.document = options.document || document;
+
+  // FF can be really hard to debug if doc is null, so we check early on
+  if (!this.document) {
+    throw new Error('No document');
+  }
+
+  this.element =  dom.createElement(this.document, 'div');
+  this.element.classList.add(options.menuClass || 'gcli-menu');
   if (options && options.field) {
-    this.element.className += ' gcliMenuField';
+    this.element.classList.add(options.menuFieldClass || 'gcli-menu-field');
   }
 
   // Pull the HTML into the DOM, but don't add it to the document
   if (menuCss != null) {
-    this.style = dom.importCss(menuCss, document);
-  }
-
-  var templates = dom.createElement(document, 'div');
+    this.style = dom.importCss(menuCss, this.document);
+  }
+
+  var templates = dom.createElement(this.document, 'div');
   dom.setInnerHtml(templates, menuHtml);
-  this.optTempl = templates.querySelector('#gcliOptTempl');
+  this.optTempl = templates.querySelector('.gcli-menu-template');
 
   // Contains the items that should be displayed
   this.items = null;
 }
 
 /**
  * Avoid memory leaks
  */
@@ -6729,29 +6887,41 @@ Menu.prototype.show = function(items, er
 
 /**
  * Hide the menu
  */
 Menu.prototype.hide = function() {
   this.element.style.display = 'none';
 };
 
+/**
+ * Change how much vertical space this menu can take up
+ */
+Menu.prototype.setMaxHeight = function(height) {
+  this.element.style.maxHeight = height + 'px';
+};
+
 exports.Menu = Menu;
 
 
 /**
  * CommandMenu is a special menu that integrates with a Requisition to display
  * available commands.
- */
-function CommandMenu(document, requisition) {
-  Menu.call(this, document);
-  this.requisition = requisition;
+ * @param options A way to customize the menu display. Valid options include
+ * those valid for Menu(), plus:
+ * - requisition: The Requisition to fill out (required)
+ */
+function CommandMenu(options) {
+  Menu.call(this, options);
+  this.requisition = options.requisition;
 
   this.requisition.commandChange.add(this.onCommandChange, this);
   canon.canonChange.add(this.onCommandChange, this);
+
+  this.onCommandChange();
 }
 
 CommandMenu.prototype = Object.create(Menu.prototype);
 
 /**
  * Avoid memory leaks
  */
 CommandMenu.prototype.destroy = function() {
@@ -6762,18 +6932,18 @@ CommandMenu.prototype.destroy = function
 };
 
 /**
  * We want to fill-in the clicked command in the cli input when the user clicks
  */
 CommandMenu.prototype.onItemClick = function(ev) {
   var type = this.requisition.commandAssignment.param.type;
 
-  var text = type.stringify(ev.currentTarget.item);
-  var arg = new Argument(text);
+  var name = ev.currentTarget.querySelector('.gcli-menu-name').innerHTML;
+  var arg = new Argument(name);
   arg.suffix = ' ';
 
   var conversion = type.parse(arg);
   this.requisition.commandAssignment.setConversion(conversion);
 };
 
 /**
  * Update the various hint components to reflect the changed command
@@ -6823,78 +6993,71 @@ exports.CommandMenu = CommandMenu;
 
 define('gcli/ui/domtemplate', ['require', 'exports', 'module' ], function(require, exports, module) {
 
   Components.utils.import("resource:///modules/devtools/Templater.jsm");
   exports.Templater = Templater;
 
 });
 define("text!gcli/ui/menu.css", [], void 0);
-define("text!gcli/ui/menu.html", [], "" +
-  "<!--" +
-  "Template for the beginnings of a command menu." +
-  "This will work with things other than a command - many things are a set of" +
-  "things with a name and description." +
-  "In the command context it is evaluated once for every keypress in the cli" +
-  "when a command has not been entered." +
-  "-->" +
-  "<div id=\"gcliOptTempl\" aria-live=\"polite\">" +
-  "  <div class=\"gcliOption\" foreach=\"item in ${items}\" onclick=\"${onItemClick}\"" +
-  "      title=\"${item.manual || ''}\">" +
-  "    ${__element.item = item; ''}" +
-  "    <span class=\"gcliOptionName\">${item.name}</span>" +
-  "    <span class=\"gcliOptionDesc\">${item.description}</span>" +
-  "  </div>" +
-  "  <div class=\"gcliMenuError\" if=\"${error}\">${error}</div>" +
-  "</div>" +
+define("text!gcli/ui/menu.html", [], "\n" +
+  "<table class=\"gcli-menu-template\" aria-live=\"polite\">\n" +
+  "  <tr class=\"gcli-menu-option\" foreach=\"item in ${items}\"\n" +
+  "      onclick=\"${onItemClick}\" title=\"${item.manual || ''}\">\n" +
+  "    <td class=\"gcli-menu-name\">${item.name}</td>\n" +
+  "    <td class=\"gcli-menu-desc\">${item.description}</td>\n" +
+  "  </tr>\n" +
+  "  <tr if=\"${error}\">\n" +
+  "    <td class=\"gcli-menu-error\" colspan=\"2\">${error}</td>\n" +
+  "  </tr>\n" +
+  "</table>\n" +
   "");
 
 define("text!gcli/ui/arg_fetch.css", [], void 0);
-define("text!gcli/ui/arg_fetch.html", [], "" +
-  "<!--" +
-  "Template for an Assignment." +
-  "Evaluated each time the commandAssignment changes" +
-  "-->" +
-  "<div id=\"gcliReqTempl\" aria-live=\"polite\">" +
-  "  <div>" +
-  "    <div class=\"gcliCmdDesc\">" +
-  "      ${requisition.commandAssignment.getValue().description}" +
-  "    </div>" +
-  "    <table class=\"gcliParams\">" +
-  "      <tbody class=\"gcliAssignment\"" +
-  "          foreach=\"assignment in ${requisition.getAssignments()}\">" +
-  "        <!-- Parameter -->" +
-  "        <tr class=\"gcliGroupRow\">" +
-  "          <td class=\"gcliParamName\">" +
-  "            <label for=\"gcliForm${assignment.param.name}\">" +
-  "              ${assignment.param.description ? assignment.param.description + ':' : ''}" +
-  "            </label>" +
-  "          </td>" +
-  "          <td class=\"gcliParamInput\">${getInputFor(assignment)}</td>" +
-  "          <td>" +
-  "            <span class=\"gcliRequired\" if=\"${assignment.param.isDataRequired()}\"> *</span>" +
-  "          </td>" +
-  "        </tr>" +
-  "        <tr class=\"gcliGroupRow\">" +
-  "          <td class=\"gcliParamError\" colspan=\"2\">" +
-  "            ${linkMessageElement(assignment, __element)}" +
-  "          </td>" +
-  "        </tr>" +
-  "      </tbody>" +
-  "      <tfoot>" +
-  "        <tr>" +
-  "          <td colspan=\"3\" class=\"gcliParamSubmit\">" +
-  "            <input type=\"submit\" value=\"Cancel\" onclick=\"${onFormCancel}\"/>" +
-  "            <input type=\"submit\" value=\"OK\" onclick=\"${onFormOk}\" save=\"${okElement}\"/>" +
-  "          </td>" +
-  "        </tr>" +
-  "      </tfoot>" +
-  "    </table>" +
-  "  </div>" +
-  "</div>" +
+define("text!gcli/ui/arg_fetch.html", [], "\n" +
+  "<!--\n" +
+  "Template for an Assignment.\n" +
+  "Evaluated each time the commandAssignment changes\n" +
+  "-->\n" +
+  "<div class=\"gcli-af-template\" aria-live=\"polite\">\n" +
+  "  <div>\n" +
+  "    <div class=\"gcli-af-cmddesc\">\n" +
+  "      ${requisition.commandAssignment.getValue().description}\n" +
+  "    </div>\n" +
+  "    <table class=\"gcli-af-params\">\n" +
+  "      <tbody foreach=\"assignment in ${requisition.getAssignments()}\">\n" +
+  "        <!-- Parameter -->\n" +
+  "        <tr>\n" +
+  "          <td class=\"gcli-af-paramname\">\n" +
+  "            <label for=\"gcliForm${assignment.param.name}\">\n" +
+  "              ${assignment.param.description ? assignment.param.description + ':' : ''}\n" +
+  "            </label>\n" +
+  "          </td>\n" +
+  "          <td>${getInputFor(assignment)}</td>\n" +
+  "          <td>\n" +
+  "            <span class=\"gcli-af-required\" if=\"${assignment.param.isDataRequired()}\">*</span>\n" +
+  "          </td>\n" +
+  "        </tr>\n" +
+  "        <tr>\n" +
+  "          <td class=\"gcli-af-error\" colspan=\"2\">\n" +
+  "            ${linkMessageElement(assignment, __element)}\n" +
+  "          </td>\n" +
+  "        </tr>\n" +
+  "      </tbody>\n" +
+  "      <tfoot>\n" +
+  "        <tr>\n" +
+  "          <td colspan=\"3\" class=\"gcli-af-submit\">\n" +
+  "            <input type=\"submit\" value=\"Cancel\" onclick=\"${onFormCancel}\"/>\n" +
+  "            <input type=\"submit\" value=\"OK\" onclick=\"${onFormOk}\" save=\"${okElement}\"/>\n" +
+  "          </td>\n" +
+  "        </tr>\n" +
+  "      </tfoot>\n" +
+  "    </table>\n" +
+  "  </div>\n" +
+  "</div>\n" +
   "");
 
 /*
  * Copyright 2009-2011 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.txt or:
  * http://opensource.org/licenses/BSD-3-Clause
  */
 
--- a/browser/devtools/webconsole/test/browser/browser_gcli_integrate.js
+++ b/browser/devtools/webconsole/test/browser/browser_gcli_integrate.js
@@ -31,16 +31,17 @@ function onLoad() {
     openConsole();
 
     testCreateCommands();
     testCallCommands();
     testRemoveCommands();
   }
   catch (ex) {
     gcli._internal.console.error('Test Failure', ex);
+    ok(false, '' + ex);
   }
   finally {
     closeConsole();
     finishTest();
   }
 }
 
 let tselarr = {
@@ -77,17 +78,17 @@ function testCallCommands() {
 
   // Test unsuccessful auto-completion
   gcliterm.inputNode.value = "ec";
   gcliterm.inputNode.focus();
   EventUtils.synthesizeKey("d", {});
   is(gcliterm.completeNode.textContent, " ecd", "Completion for \"ecd\"");
 
   // Test a normal command's life cycle
-  gcliterm.opts.inputter.setInput("echo hello world");
+  gcliterm.opts.display.inputter.setInput("echo hello world");
   gcliterm.opts.requisition.exec();
 
   let nodes = hud.outputNode.querySelectorAll("description");
 
   is(nodes.length, 2, "Right number of output nodes");
   ok(/hello world/.test(nodes[0].textContent), "the command's output is correct.");
 
   gcliterm.clearOutput();
--- a/browser/devtools/webconsole/test/browser/browser_gcli_web.js
+++ b/browser/devtools/webconsole/test/browser/browser_gcli_web.js
@@ -908,17 +908,17 @@ function update(input) {
   if (debug) {
     console.log('####### TEST: typed="' + input.typed +
         '" cur=' + input.cursor.start +
         ' cli=', requ);
   }
 
   status = requ.getStatus();
   assignC = requ.getAssignmentAt(input.cursor.start);
-  statuses = requ.getInputStatusMarkup().map(function(s) {
+  statuses = requ.getInputStatusMarkup(input.cursor.start).map(function(s) {
     return s.toString()[0];
   }).join('');
 
   if (requ.commandAssignment.getValue()) {
     assign1 = requ.getAssignment(0);
     assign2 = requ.getAssignment(1);
   }
   else {
@@ -1426,17 +1426,17 @@ function input(typed) {
 
   if (debug) {
     console.log('####### TEST: typed="' + typed +
         '" cur=' + cursor.start +
         ' cli=', requ);
   }
 
   status = requ.getStatus();
-  statuses = requ.getInputStatusMarkup().map(function(s) {
+  statuses = requ.getInputStatusMarkup(input.cursor.start).map(function(s) {
     return s.toString()[0];
   }).join('');
 
   if (requ.commandAssignment.getValue()) {
     assign = requ.getAssignment(0);
   }
   else {
     assign = undefined;
@@ -1583,16 +1583,17 @@ function onLoad() {
 
   try {
     openConsole();
     define.globalDomain.require("gclitest/index");
   }
   catch (ex) {
     failed = ex;
     console.error('Test Failure', ex);
+    ok(false, '' + ex);
   }
   finally {
     closeConsole();
     finish();
   }
 
   if (failed) {
     throw failed;
--- a/browser/devtools/webconsole/test/browser/browser_webconsole_bug_601667_filter_buttons.js
+++ b/browser/devtools/webconsole/test/browser/browser_webconsole_bug_601667_filter_buttons.js
@@ -16,17 +16,17 @@ function testFilterButtons() {
 
   let hud = HUDService.getHudByWindow(content);
   hudId = hud.hudId;
   hudBox = hud.HUDBox;
 
   testMenuFilterButton("net");
   testMenuFilterButton("css");
   testMenuFilterButton("js");
-  testMenuFilterButton("webdev");
+  testMenuFilterButton("logging");
 
   finishTest();
 }
 
 function testMenuFilterButton(aCategory) {
   let selector = ".webconsole-filter-button[category=\"" + aCategory + "\"]";
   let button = hudBox.querySelector(selector);
   ok(button, "we have the \"" + aCategory + "\" button");
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -9,16 +9,17 @@
 @DLL_PREFIX@xpcom_compat@DLL_SUFFIX@
 @DLL_PREFIX@xpistub@DLL_SUFFIX@
 @DLL_PREFIX@zlib@DLL_SUFFIX@
 @DLL_PREFIX@jemalloc@DLL_SUFFIX@
 #ifdef MOZ_STATIC_JS
 @DLL_PREFIX@mozjs@DLL_SUFFIX@
 #endif
 LICENSE
+update.locale
 browserconfig.properties
 chrome/US.jar
 chrome/app-chrome.manifest
 chrome/browser.manifest
 chrome/chrome.rdf
 chrome/chromelist.txt
 chrome/classic.jar
 chrome/classic.manifest
--- a/browser/locales/en-US/chrome/browser/devtools/gcli.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/gcli.properties
@@ -15,17 +15,17 @@ canonDescNone=(No description)
 # of JavaScript like traditional developer tool command lines. This describes
 # the '{' command.
 cliEvalJavascript=Enter JavaScript directly
 
 # LOCALIZATION NOTE (fieldSelectionSelect): When a command has a parameter
 # that has a number of pre-defined options the user interface presents these
 # in a drop-down menu, where the first 'option' is an indicator that a
 # selection should be made. This string describes that first option.
-fieldSelectionSelect=Select a %S ...
+fieldSelectionSelect=Select a %S …
 
 # LOCALIZATION NOTE (fieldArrayAdd): When a command has a parameter that can
 # be repeated a number of times (e.g. like the 'cat a.txt b.txt' command) the
 # user interface presents buttons to add and remove arguments. This string is
 # used to add arguments.
 fieldArrayAdd=Add
 
 # LOCALIZATION NOTE (fieldArrayDel): When a command has a parameter that can
--- a/browser/locales/en-US/chrome/browser/devtools/inspector.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/inspector.properties
@@ -1,8 +1,17 @@
+# LOCALIZATION NOTE These strings are used inside the Inspector
+# which is available from the Web Developer sub-menu -> 'Inspect'.
+#
+# The correct localization of this file might be to keep it in
+# English, or another language commonly spoken among web developers.
+# You want to make that choice consistent across the developer tools.
+# A good criteria is the language in which you'd find the best
+# documentation on web development on the web.
+
 # LOCALIZATION NOTE (confirmNavigationAway): Used in the Inspector tool, when
 # the user tries to navigate away from a web page, to confirm the change of
 # page.
 confirmNavigationAway.message=Leaving this page will close the Inspector and the changes you have made will be lost.
 confirmNavigationAway.buttonLeave=Leave Page
 confirmNavigationAway.buttonLeaveAccesskey=L
 confirmNavigationAway.buttonStay=Stay on Page
 confirmNavigationAway.buttonStayAccesskey=S
--- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd
@@ -1,11 +1,17 @@
 <!-- LOCALIZATION NOTE : FILE This file contains the Scratchpad window strings -->
 <!-- LOCALIZATION NOTE : FILE Do not translate commandkeys -->
 
+<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
+  - keep it in English, or another language commonly spoken among web developers.
+  - You want to make that choice consistent across the developer tools.
+  - A good criteria is the language in which you'd find the best
+  - documentation on web development on the web. -->
+
 <!-- LOCALIZATION NOTE (scratchpad.title):
   -  The Scratchpad is intended to provide a simple text editor for creating
   -  and evaluating bits of JavaScript code for the purposes of function
   -  prototyping, experimentation and convenient scripting.
   -
   -  It's quite possible that you won't have a good analogue for the word
   -  "Scratchpad" in your locale. You should feel free to find a close
   -  approximation to it or choose a word (or words) that means
--- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.properties
@@ -1,8 +1,17 @@
+# LOCALIZATION NOTE These strings are used inside the JavaScript scratchpad
+# which is available from the Web Developer sub-menu -> 'Scratchpad'.
+#
+# The correct localization of this file might be to keep it in
+# English, or another language commonly spoken among web developers.
+# You want to make that choice consistent across the developer tools.
+# A good criteria is the language in which you'd find the best
+# documentation on web development on the web.
+
 # LOCALIZATION NOTE  (propertyPanel.updateButton.label): Used in the Property
 # Panel that is opened by the Scratchpad window when inspecting an object. This
 # is the Update button label.
 propertyPanel.updateButton.label=Update
 propertyPanel.updateButton.accesskey=U
 
 # LOCALIZATION NOTE  (export.fileOverwriteConfirmation): This is displayed when
 # the user attempts to save to an already existing file.
--- a/browser/locales/en-US/chrome/browser/devtools/styleinspector.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/styleinspector.dtd
@@ -1,8 +1,14 @@
+<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
+  - keep it in English, or another language commonly spoken among web developers.
+  - You want to make that choice consistent across the developer tools.
+  - A good criteria is the language in which you'd find the best
+  - documentation on web development on the web. -->
+
 <!-- LOCALIZATION NOTE (userStylesLabel): This is the label for the checkbox
   -  that specifies whether the styles that are not from the user's stylesheet
   -  should be displayed or not. -->
 <!ENTITY userStylesLabel    "Only user styles">
 
 <!-- LOCALIZATION NOTE (userStylesSearch): This is the placeholder that goes in
   -  the search box when no search term has been entered. -->
 <!ENTITY userStylesSearch      "Search">
--- a/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties
@@ -1,9 +1,16 @@
 # LOCALIZATION NOTE These strings are used inside the Style Inspector.
+#
+# The correct localization of this file might be to keep it in
+# English, or another language commonly spoken among web developers.
+# You want to make that choice consistent across the developer tools.
+# A good criteria is the language in which you'd find the best
+# documentation on web development on the web.
+
 
 # LOCALIZATION NOTE (panelTitle): This is the panel title
 panelTitle=Style Inspector
 
 # LOCALIZATION NOTE (rule.status): For each style property the panel shows
 # the rules which hold that specific property. For every rule, the rule status
 # is also displayed: a rule can be the best match, a match, a parent match, or a
 # rule did not match the element the user has highlighted.
--- a/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd
@@ -1,8 +1,14 @@
+<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
+  - keep it in English, or another language commonly spoken among web developers.
+  - You want to make that choice consistent across the developer tools.
+  - A good criteria is the language in which you'd find the best
+  - documentation on web development on the web. -->
+
 <!ENTITY networkPanel.requestURL                  "Request URL">
 <!ENTITY networkPanel.requestMethod               "Request Method">
 <!ENTITY networkPanel.statusCode                  "Status Code">
 
 <!ENTITY networkPanel.requestHeaders              "Request Headers">
 <!ENTITY networkPanel.requestCookie               "Sent Cookie">
 <!ENTITY networkPanel.requestBody                 "Request Body">
 <!ENTITY networkPanel.requestFormData             "Sent Form Data">
--- a/browser/locales/en-US/chrome/browser/devtools/webconsole.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/webconsole.properties
@@ -1,8 +1,15 @@
+# LOCALIZATION NOTE
+# The correct localization of this file might be to keep it in
+# English, or another language commonly spoken among web developers.
+# You want to make that choice consistent across the developer tools.
+# A good criteria is the language in which you'd find the best
+# documentation on web development on the web.
+
 typeError=Error: 
 typeWarning=Warning: 
 typeNetwork=Network: 
 typeException=Exception:  
 typeCssParser=CSS Parser: 
 typeStrict=Strict Warning: 
 msgCategory=Category: 
 errLine=Line: %S
@@ -13,29 +20,27 @@ categoryConsole=Console:
 btnMutation=DOM Mutation
 tipMutation=Toggle DOM Mutation event logging
 btnPageNet=Net
 tipPageNet=Log network access
 btnPageCSS=CSS
 tipPageCSS=Log CSS parsing errors
 btnPageJS=JS
 tipPageJS=Log JavaScript exceptions
-# LOCALIZATION NOTE (btnPageWebDeveloper):
+# LOCALIZATION NOTE (btnPageLogging):
 #
-# This is used as the text of the "Web Developer" button on the toolbar. It
+# This is used as the text of the "Logging" button on the toolbar. It
 # shows or hides messages that the web developer inserted on the page for
-# debugging purposes, using calls such console.log() and console.error(). You
-# may wish to localize this as "Page" if that is clearer in your locale. See
-# bug 601667 for more information.
-btnPageWebDeveloper=Web Developer
-# LOCALIZATION NOTE (tipPageWebDeveloper):
+# debugging purposes, using calls such console.log() and console.error().
+btnPageLogging=Logging
+# LOCALIZATION NOTE (tipPageLogging):
 #
-# This is used as the text of the tool tip for the "Web Developer" button on
+# This is used as the text of the tool tip for the "Logging" button on
 # the toolbar.
-tipPageWebDeveloper=Log messages sent to the "console" object
+tipPageLogging=Log messages sent to the "console" object
 btnConsoleErrors=Errors
 tipConsoleErrors=Log calls to console.error()
 btnConsoleInfo=Info
 tipConsoleInfo=Log calls to console.info()
 btnConsoleWarnings=Warnings
 tipConsoleWarnings=Log calls to console.warn()
 btnConsoleLog=Log
 tipConsoleLog=Log calls to console.log()
--- a/browser/themes/gnomestripe/devtools/gcli.css
+++ b/browser/themes/gnomestripe/devtools/gcli.css
@@ -31,211 +31,256 @@
  * 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 ***** */
 
 /* From: $GCLI/mozilla/gcli/ui/gcliterm.css */
+
+/* Bug 678152 calls for UX review which will fix the color names */
+
 .gcliterm-input-node,
 .gcliterm-complete-node {
   border: none;
   -moz-appearance: none;
   height: 100%;
   vertical-align: middle;
   background-color: transparent;
   font: 12px Consolas, "Lucida Console", monospace;
-  padding: 2px 0 0 16px;
+}
+
+.gcliterm-input-node {
+  padding-top: 2px;
+  padding-bottom: 0;
+  -moz-padding-start: 16px;
+  -moz-padding-end: 0;
 }
 
 .gcliterm-complete-node {
   color: #FFF;
-  padding: 4px 4px 2px 21px;
+  padding-top: 4px;
+  padding-bottom: 2px;
+  -moz-padding-start: 21px;
+  -moz-padding-end: 4px;
 }
 
-.gcliVALID {
+.gcli-in-valid {
   border-bottom: none;
 }
 
-.gcliINCOMPLETE {
+.gcli-in-incomplete {
   color: #DDD;
   border-bottom: 1px dotted #999;
 }
 
-.gcliERROR {
+.gcli-in-error {
   color: #DDD;
   border-bottom: 1px dotted #F00;
 }
 
-.gcliCompl {
+.gcli-in-ontab {
   color: #999;
 }
 
 .gcliterm-stack-node {
   background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
   width: 100%;
 }
 
+.gcliterm-argfetcher {
+  display: -moz-box;
+  -moz-box-flex: 1;
+}
+
 .gcliterm-hint-node {
-  color: #000;
-  background: rgba(250, 250, 250, 0.8);
-  border: 1px solid #AAA;
-  border-bottom: 0px !important;
+  border-top: 1px solid threedshadow;
+  border-bottom: 1px solid #FFF;
+  border-left: 1px solid threedshadow;
+  border-right: 1px solid threedshadow;
   border-top-right-radius: 5px;
   border-top-left-radius: 5px;
-  margin-left: 10px;
-  margin-right: 10px;
-  display: inline-block;
-  overflow: auto;
-  padding: 10px;
+  margin-bottom: -1px;
 }
 
 .gcliterm-hint-parent {
-  border-bottom: 1px solid #AAA;
+  width: 300px;
+  padding: 10px 10px 0;
+  border-top: 1px solid threedshadow;
+  border-bottom: 1px solid threedshadow;
 }
 
-.gcliCmdHelpRight {
+.gcli-help-right {
   text-align: right;
 }
 
+.gcliterm-menu {
+  display: -moz-box;
+  -moz-box-flex: 1;
+}
+
+.gcliterm-hint-nospace {
+  display: none;
+}
+
+/*
+ * The language of a console is not en_US or any other common language
+ * (i.e we don't attempt to translate 'console.log(x)')
+ * So we fix .gcliterm-input-node/.gcliterm-complete-node elements to be ltr.
+ * As a result we also want the hints to pop up on the left (above the prompt)
+ */
+.gcliterm-input-node,
+.gcliterm-complete-node,
+.gcliterm-display {
+  direction: ltr;
+}
+
+/*
+ * We want the stuff under .gcliterm-display to obey normal direction rules
+ * so we need to swap back when the document is in rtl mode.
+ * The selectors below are faster, but equivalent to:
+ * .gcliterm-display > *:-moz-locale-dir(rtl) {
+ *   direction: rtl;
+ * }
+ * In non-performance critical situations the above is preferred due to it's
+ * greater resilience to refactoring
+ */
+.gcliterm-hint-parent:-moz-locale-dir(rtl),
+.hud-output-node:-moz-locale-dir(rtl) {
+  direction: rtl;
+}
+
+/* From: $GCLI/mozilla/gcli/ui/gcliterm-gnomestripe.css */
+
 /* From: $GCLI/lib/gcli/ui/arg_fetch.css */
-.gcliCmdDesc {
+
+.gcli-argfetch {
+  width: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+}
+
+.gcli-af-cmddesc {
   font-weight: bold;
   text-align: center;
   margin-bottom: 5px;
-  border-bottom: 1px solid #ddd;
-  padding-bottom: 3px;
+  padding: 3px 10px 0;
 }
 
-.gcliParamGroup {
-  font-weight: bold;
+.gcli-af-params {
+  padding: 0 10px;
+  width: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
 }
 
-.gcliParamName {
+.gcli-af-paramname {
   text-align: right;
   font-size: 90%;
 }
 
-.gcliParamError {
+.gcli-af-required {
+  font-size: 90%;
+  color: #f66;
+  padding-left: 5px;
+}
+
+.gcli-af-error {
   font-size: 80%;
   color: #900;
 }
 
-.gcliParamSubmit {
+.gcli-af-submit {
   text-align: right;
 }
 
-.gcliGroupSymbol {
-  font-size: 90%;
-  color: #666;
-}
-
-.gcliRequired {
-  font-size: 80%;
-  color: #666;
-}
-
-.gcliParams {
+.gcli-field {
   width: 100%;
 }
 
-/* From: $GCLI/lib/gcli/ui/hinter.css */
-.gcliHintParent {
-  color: #000;
-  background: rgba(250, 250, 250, 0.8);
-  border: 1px solid #AAA;
-  border-top-right-radius: 5px;
-  border-top-left-radius: 5px;
-  margin-left: 10px;
-  margin-right: 10px;
-  display: inline-block;
+/* From: $GCLI/lib/gcli/ui/menu.css */
+
+.gcli-menu {
+  width: 100%;
   overflow: hidden;
 }
 
-.gcliHints {
-  overflow: auto;
-  padding: 10px;
-  display: inline-block;
+.gcli-menu-field {
+  border: 1px solid #aaa;
+  border-top: 0;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 5px;
+  max-height: 300px;
+  margin: 0 3px;
+  padding: 0;
 }
 
-.gcliHints ul {
-  margin: 0;
-  padding: 0 15px;
+.gcli-menu-template {
+  border-collapse: collapse;
+  width: 100%;
+  margin: 10px 0;
 }
 
-/* From: $GCLI/lib/gcli/ui/menu.css */
-.gcliOption {
+.gcli-menu-option {
   overflow: hidden;
   white-space: nowrap;
   cursor: pointer;
   padding: 2px;
 }
 
-.gcliOption:hover {
+.gcli-menu-option:hover {
   background-color: rgb(230, 230, 230);
 }
 
-.gcliOptionName {
-  padding-right: 5px;
+.gcli-menu-name {
+  padding-top: 0;
+  padding-bottom: 0;
+  -moz-padding-start: 10px;
+  -moz-padding-end: 2px;
 }
 
-.gcliOptionDesc {
+.gcli-menu-desc {
   font-size: 80%;
   color: #999;
 }
 
-.gcliMenuError {
+.gcli-menu-error {
   overflow: hidden;
   white-space: nowrap;
-  padding: 8px 2px 2px 2px;
+  padding-top: 8px;
+  padding-bottom: 2px;
+  -moz-padding-start: 10px;
+  -moz-padding-end: 2px;
   font-size: 80%;
   color: red;
 }
 
-.gcliMenuField {
-  background-color: white;
-  color: black;
-  border: 1px solid #aaa;
-  padding: 2px;
-  max-height: 300px;
-  overflow-y: auto;
-  max-width: 220px;
-  overflow-x: hidden;
-  margin: 0px 10px;
-  border-top: 0px !important;
-  border-bottom-right-radius: 5px;
-  border-bottom-left-radius: 5px;
-}
+/* From: $GCLI/lib/gcli/ui/inputter.css */
 
-/* From: $GCLI/lib/gcli/ui/inputter.css */
-.gcliCompletion {
+.gcli-in-complete {
   position: absolute;
   z-index: -1000;
-  background-color: #DDD;
   border: 1px transparent solid;
   padding: 1px 1px 1px 2px;
-}
-
-.gcliCompletion {
   color: #DDD;
 }
 
-.gcliINCOMPLETE {
+.gcli-in-incomplete {
   border-bottom: 2px dotted #999;
 }
 
-.gcliERROR {
+.gcli-in-error {
   border-bottom: 2px dotted #F00;
 }
 
-.gcliPrompt {
+.gcli-in-ontab {
+  color: #999;
+}
+
+.gcli-in-closebrace {
+  color: #999;
+}
+
+.gcli-prompt {
   color: #66F;
   font-weight: bold;
 }
-
-.gcliCompl {
-  color: #999;
-}
-
-.gcliCloseBrace {
-  color: #999;
-}
--- a/browser/themes/pinstripe/devtools/gcli.css
+++ b/browser/themes/pinstripe/devtools/gcli.css
@@ -31,211 +31,260 @@
  * 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 ***** */
 
 /* From: $GCLI/mozilla/gcli/ui/gcliterm.css */
+
+/* Bug 678152 calls for UX review which will fix the color names */
+
 .gcliterm-input-node,
 .gcliterm-complete-node {
   border: none;
   -moz-appearance: none;
   height: 100%;
   vertical-align: middle;
   background-color: transparent;
   font: 12px Consolas, "Lucida Console", monospace;
-  padding: 2px 0 0 16px;
+}
+
+.gcliterm-input-node {
+  padding-top: 2px;
+  padding-bottom: 0;
+  -moz-padding-start: 16px;
+  -moz-padding-end: 0;
 }
 
 .gcliterm-complete-node {
   color: #FFF;
-  padding: 4px 4px 2px 21px;
+  padding-top: 4px;
+  padding-bottom: 2px;
+  -moz-padding-start: 21px;
+  -moz-padding-end: 4px;
 }
 
-.gcliVALID {
+.gcli-in-valid {
   border-bottom: none;
 }
 
-.gcliINCOMPLETE {
+.gcli-in-incomplete {
   color: #DDD;
   border-bottom: 1px dotted #999;
 }
 
-.gcliERROR {
+.gcli-in-error {
   color: #DDD;
   border-bottom: 1px dotted #F00;
 }
 
-.gcliCompl {
+.gcli-in-ontab {
   color: #999;
 }
 
 .gcliterm-stack-node {
   background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
   width: 100%;
 }
 
+.gcliterm-argfetcher {
+  display: -moz-box;
+  -moz-box-flex: 1;
+}
+
 .gcliterm-hint-node {
-  color: #000;
-  background: rgba(250, 250, 250, 0.8);
-  border: 1px solid #AAA;
-  border-bottom: 0px !important;
+  border-top: 1px solid threedshadow;
+  border-bottom: 1px solid #FFF;
+  border-left: 1px solid threedshadow;
+  border-right: 1px solid threedshadow;
   border-top-right-radius: 5px;
   border-top-left-radius: 5px;
-  margin-left: 10px;
-  margin-right: 10px;
-  display: inline-block;
-  overflow: auto;
-  padding: 10px;
+  margin-bottom: -1px;
 }
 
 .gcliterm-hint-parent {
-  border-bottom: 1px solid #AAA;
+  width: 300px;
+  padding: 10px 10px 0;
+  border-top: 1px solid threedshadow;
+  border-bottom: 1px solid threedshadow;
+}
+
+.gcli-help-right {
+  text-align: right;
+}
+
+.gcliterm-menu {
+  display: -moz-box;
+  -moz-box-flex: 1;
+}
+
+.gcliterm-hint-nospace {
+  display: none;
 }
 
-.gcliCmdHelpRight {
-  text-align: right;
+/*
+ * The language of a console is not en_US or any other common language
+ * (i.e we don't attempt to translate 'console.log(x)')
+ * So we fix .gcliterm-input-node/.gcliterm-complete-node elements to be ltr.
+ * As a result we also want the hints to pop up on the left (above the prompt)
+ */
+.gcliterm-input-node,
+.gcliterm-complete-node,
+.gcliterm-display {
+  direction: ltr;
+}
+
+/*
+ * We want the stuff under .gcliterm-display to obey normal direction rules
+ * so we need to swap back when the document is in rtl mode.
+ * The selectors below are faster, but equivalent to:
+ * .gcliterm-display > *:-moz-locale-dir(rtl) {
+ *   direction: rtl;
+ * }
+ * In non-performance critical situations the above is preferred due to it's
+ * greater resilience to refactoring
+ */
+.gcliterm-hint-parent:-moz-locale-dir(rtl),
+.hud-output-node:-moz-locale-dir(rtl) {
+  direction: rtl;
+}
+
+/* From: $GCLI/mozilla/gcli/ui/gcliterm-pinstripe.css */
+
+.gcliterm-complete-node {
+  padding-top: 6px !important;
 }
 
 /* From: $GCLI/lib/gcli/ui/arg_fetch.css */
-.gcliCmdDesc {
+
+.gcli-argfetch {
+  width: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+}
+
+.gcli-af-cmddesc {
   font-weight: bold;
   text-align: center;
   margin-bottom: 5px;
-  border-bottom: 1px solid #ddd;
-  padding-bottom: 3px;
+  padding: 3px 10px 0;
 }
 
-.gcliParamGroup {
-  font-weight: bold;
+.gcli-af-params {
+  padding: 0 10px;
+  width: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
 }
 
-.gcliParamName {
+.gcli-af-paramname {
   text-align: right;
   font-size: 90%;
 }
 
-.gcliParamError {
+.gcli-af-required {
+  font-size: 90%;
+  color: #f66;
+  padding-left: 5px;
+}
+
+.gcli-af-error {
   font-size: 80%;
   color: #900;
 }
 
-.gcliParamSubmit {
+.gcli-af-submit {
   text-align: right;
 }
 
-.gcliGroupSymbol {
-  font-size: 90%;
-  color: #666;
-}
-
-.gcliRequired {
-  font-size: 80%;
-  color: #666;
-}
-
-.gcliParams {
+.gcli-field {
   width: 100%;
 }
 
-/* From: $GCLI/lib/gcli/ui/hinter.css */
-.gcliHintParent {
-  color: #000;
-  background: rgba(250, 250, 250, 0.8);
-  border: 1px solid #AAA;
-  border-top-right-radius: 5px;
-  border-top-left-radius: 5px;
-  margin-left: 10px;
-  margin-right: 10px;
-  display: inline-block;
+/* From: $GCLI/lib/gcli/ui/menu.css */
+
+.gcli-menu {
+  width: 100%;
   overflow: hidden;
 }
 
-.gcliHints {
-  overflow: auto;
-  padding: 10px;
-  display: inline-block;
+.gcli-menu-field {
+  border: 1px solid #aaa;
+  border-top: 0;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 5px;
+  max-height: 300px;
+  margin: 0 3px;
+  padding: 0;
 }
 
-.gcliHints ul {
-  margin: 0;
-  padding: 0 15px;
+.gcli-menu-template {
+  border-collapse: collapse;
+  width: 100%;
+  margin: 10px 0;
 }
 
-/* From: $GCLI/lib/gcli/ui/menu.css */
-.gcliOption {
+.gcli-menu-option {
   overflow: hidden;
   white-space: nowrap;
   cursor: pointer;
   padding: 2px;
 }
 
-.gcliOption:hover {
+.gcli-menu-option:hover {
   background-color: rgb(230, 230, 230);
 }
 
-.gcliOptionName {
-  padding-right: 5px;
+.gcli-menu-name {
+  padding-top: 0;
+  padding-bottom: 0;
+  -moz-padding-start: 10px;
+  -moz-padding-end: 2px;
 }
 
-.gcliOptionDesc {
+.gcli-menu-desc {
   font-size: 80%;
   color: #999;
 }
 
-.gcliMenuError {
+.gcli-menu-error {
   overflow: hidden;
   white-space: nowrap;
-  padding: 8px 2px 2px 2px;
+  padding-top: 8px;
+  padding-bottom: 2px;
+  -moz-padding-start: 10px;
+  -moz-padding-end: 2px;
   font-size: 80%;
   color: red;
 }
 
-.gcliMenuField {
-  background-color: white;
-  color: black;
-  border: 1px solid #aaa;
-  padding: 2px;
-  max-height: 300px;
-  overflow-y: auto;
-  max-width: 220px;
-  overflow-x: hidden;
-  margin: 0px 10px;
-  border-top: 0px !important;
-  border-bottom-right-radius: 5px;
-  border-bottom-left-radius: 5px;
-}
+/* From: $GCLI/lib/gcli/ui/inputter.css */
 
-/* From: $GCLI/lib/gcli/ui/inputter.css */
-.gcliCompletion {
+.gcli-in-complete {
   position: absolute;
   z-index: -1000;
-  background-color: #DDD;
   border: 1px transparent solid;
   padding: 1px 1px 1px 2px;
-}
-
-.gcliCompletion {
   color: #DDD;
 }
 
-.gcliINCOMPLETE {
+.gcli-in-incomplete {
   border-bottom: 2px dotted #999;
 }
 
-.gcliERROR {
+.gcli-in-error {
   border-bottom: 2px dotted #F00;
 }
 
-.gcliPrompt {
+.gcli-in-ontab {
+  color: #999;
+}
+
+.gcli-in-closebrace {
+  color: #999;
+}
+
+.gcli-prompt {
   color: #66F;
   font-weight: bold;
 }
-
-.gcliCompl {
-  color: #999;
-}
-
-.gcliCloseBrace {
-  color: #999;
-}
--- a/browser/themes/winstripe/devtools/gcli.css
+++ b/browser/themes/winstripe/devtools/gcli.css
@@ -31,211 +31,256 @@
  * 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 ***** */
 
 /* From: $GCLI/mozilla/gcli/ui/gcliterm.css */
+
+/* Bug 678152 calls for UX review which will fix the color names */
+
 .gcliterm-input-node,
 .gcliterm-complete-node {
   border: none;
   -moz-appearance: none;
   height: 100%;
   vertical-align: middle;
   background-color: transparent;
   font: 12px Consolas, "Lucida Console", monospace;
-  padding: 2px 0 0 16px;
+}
+
+.gcliterm-input-node {
+  padding-top: 2px;
+  padding-bottom: 0;
+  -moz-padding-start: 16px;
+  -moz-padding-end: 0;
 }
 
 .gcliterm-complete-node {
   color: #FFF;
-  padding: 4px 4px 2px 21px;
+  padding-top: 4px;
+  padding-bottom: 2px;
+  -moz-padding-start: 21px;
+  -moz-padding-end: 4px;
 }
 
-.gcliVALID {
+.gcli-in-valid {
   border-bottom: none;
 }
 
-.gcliINCOMPLETE {
+.gcli-in-incomplete {
   color: #DDD;
   border-bottom: 1px dotted #999;
 }
 
-.gcliERROR {
+.gcli-in-error {
   color: #DDD;
   border-bottom: 1px dotted #F00;
 }
 
-.gcliCompl {
+.gcli-in-ontab {
   color: #999;
 }
 
 .gcliterm-stack-node {
   background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
   width: 100%;
 }
 
+.gcliterm-argfetcher {
+  display: -moz-box;
+  -moz-box-flex: 1;
+}
+
 .gcliterm-hint-node {
-  color: #000;
-  background: rgba(250, 250, 250, 0.8);
-  border: 1px solid #AAA;
-  border-bottom: 0px !important;
+  border-top: 1px solid threedshadow;
+  border-bottom: 1px solid #FFF;
+  border-left: 1px solid threedshadow;
+  border-right: 1px solid threedshadow;
   border-top-right-radius: 5px;
   border-top-left-radius: 5px;
-  margin-left: 10px;
-  margin-right: 10px;
-  display: inline-block;
-  overflow: auto;
-  padding: 10px;
+  margin-bottom: -1px;
 }
 
 .gcliterm-hint-parent {
-  border-bottom: 1px solid #AAA;
+  width: 300px;
+  padding: 10px 10px 0;
+  border-top: 1px solid threedshadow;
+  border-bottom: 1px solid threedshadow;
 }
 
-.gcliCmdHelpRight {
+.gcli-help-right {
   text-align: right;
 }
 
+.gcliterm-menu {
+  display: -moz-box;
+  -moz-box-flex: 1;
+}
+
+.gcliterm-hint-nospace {
+  display: none;
+}
+
+/*
+ * The language of a console is not en_US or any other common language
+ * (i.e we don't attempt to translate 'console.log(x)')
+ * So we fix .gcliterm-input-node/.gcliterm-complete-node elements to be ltr.
+ * As a result we also want the hints to pop up on the left (above the prompt)
+ */
+.gcliterm-input-node,
+.gcliterm-complete-node,
+.gcliterm-display {
+  direction: ltr;
+}
+
+/*
+ * We want the stuff under .gcliterm-display to obey normal direction rules
+ * so we need to swap back when the document is in rtl mode.
+ * The selectors below are faster, but equivalent to:
+ * .gcliterm-display > *:-moz-locale-dir(rtl) {
+ *   direction: rtl;
+ * }
+ * In non-performance critical situations the above is preferred due to it's
+ * greater resilience to refactoring
+ */
+.gcliterm-hint-parent:-moz-locale-dir(rtl),
+.hud-output-node:-moz-locale-dir(rtl) {
+  direction: rtl;
+}
+
+/* From: $GCLI/mozilla/gcli/ui/gcliterm-winstripe.css */
+
 /* From: $GCLI/lib/gcli/ui/arg_fetch.css */
-.gcliCmdDesc {
+
+.gcli-argfetch {
+  width: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+}
+
+.gcli-af-cmddesc {
   font-weight: bold;
   text-align: center;
   margin-bottom: 5px;
-  border-bottom: 1px solid #ddd;
-  padding-bottom: 3px;
+  padding: 3px 10px 0;
 }
 
-.gcliParamGroup {
-  font-weight: bold;
+.gcli-af-params {
+  padding: 0 10px;
+  width: 100%;
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
 }
 
-.gcliParamName {
+.gcli-af-paramname {
   text-align: right;
   font-size: 90%;
 }
 
-.gcliParamError {
+.gcli-af-required {
+  font-size: 90%;
+  color: #f66;
+  padding-left: 5px;
+}
+
+.gcli-af-error {
   font-size: 80%;
   color: #900;
 }
 
-.gcliParamSubmit {
+.gcli-af-submit {
   text-align: right;
 }
 
-.gcliGroupSymbol {
-  font-size: 90%;
-  color: #666;
-}
-
-.gcliRequired {
-  font-size: 80%;
-  color: #666;
-}
-
-.gcliParams {
+.gcli-field {
   width: 100%;
 }
 
-/* From: $GCLI/lib/gcli/ui/hinter.css */
-.gcliHintParent {
-  color: #000;
-  background: rgba(250, 250, 250, 0.8);
-  border: 1px solid #AAA;
-  border-top-right-radius: 5px;
-  border-top-left-radius: 5px;
-  margin-left: 10px;
-  margin-right: 10px;
-  display: inline-block;
+/* From: $GCLI/lib/gcli/ui/menu.css */
+
+.gcli-menu {
+  width: 100%;
   overflow: hidden;
 }
 
-.gcliHints {
-  overflow: auto;
-  padding: 10px;
-  display: inline-block;
+.gcli-menu-field {
+  border: 1px solid #aaa;
+  border-top: 0;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 5px;
+  max-height: 300px;
+  margin: 0 3px;
+  padding: 0;
 }
 
-.gcliHints ul {
-  margin: 0;
-  padding: 0 15px;
+.gcli-menu-template {
+  border-collapse: collapse;
+  width: 100%;
+  margin: 10px 0;
 }
 
-/* From: $GCLI/lib/gcli/ui/menu.css */
-.gcliOption {
+.gcli-menu-option {
   overflow: hidden;
   white-space: nowrap;
   cursor: pointer;
   padding: 2px;
 }
 
-.gcliOption:hover {
+.gcli-menu-option:hover {
   background-color: rgb(230, 230, 230);
 }
 
-.gcliOptionName {
-  padding-right: 5px;
+.gcli-menu-name {
+  padding-top: 0;
+  padding-bottom: 0;
+  -moz-padding-start: 10px;
+  -moz-padding-end: 2px;
 }
 
-.gcliOptionDesc {
+.gcli-menu-desc {
   font-size: 80%;
   color: #999;
 }
 
-.gcliMenuError {
+.gcli-menu-error {
   overflow: hidden;
   white-space: nowrap;
-  padding: 8px 2px 2px 2px;
+  padding-top: 8px;
+  padding-bottom: 2px;
+  -moz-padding-start: 10px;
+  -moz-padding-end: 2px;
   font-size: 80%;
   color: red;
 }
 
-.gcliMenuField {
-  background-color: white;
-  color: black;
-  border: 1px solid #aaa;
-  padding: 2px;
-  max-height: 300px;
-  overflow-y: auto;
-  max-width: 220px;
-  overflow-x: hidden;
-  margin: 0px 10px;
-  border-top: 0px !important;
-  border-bottom-right-radius: 5px;
-  border-bottom-left-radius: 5px;
-}
+/* From: $GCLI/lib/gcli/ui/inputter.css */
 
-/* From: $GCLI/lib/gcli/ui/inputter.css */
-.gcliCompletion {
+.gcli-in-complete {
   position: absolute;
   z-index: -1000;
-  background-color: #DDD;
   border: 1px transparent solid;
   padding: 1px 1px 1px 2px;
-}
-
-.gcliCompletion {
   color: #DDD;
 }
 
-.gcliINCOMPLETE {
+.gcli-in-incomplete {
   border-bottom: 2px dotted #999;
 }
 
-.gcliERROR {
+.gcli-in-error {
   border-bottom: 2px dotted #F00;
 }
 
-.gcliPrompt {
+.gcli-in-ontab {
+  color: #999;
+}
+
+.gcli-in-closebrace {
+  color: #999;
+}
+
+.gcli-prompt {
   color: #66F;
   font-weight: bold;
 }
-
-.gcliCompl {
-  color: #999;
-}
-
-.gcliCloseBrace {
-  color: #999;
-}
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -51,25 +51,80 @@ endif
 
 ifeq (WINNT,$(OS_ARCH))
 DIRS = win32
 endif
 
 DIRS += pgo
 
 ifdef ENABLE_TESTS
+  DIRS += autoconf/test
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
   DIRS += mobile/sutagent/android \
           mobile/sutagent/android/watcher \
           mobile/sutagent/android/ffxcp \
           mobile/sutagent/android/fencp \
           $(NULL)
 endif
 endif
 
+ifdef MOZ_APP_BASENAME
+DIST_FILES = application.ini
+
+ifdef LIBXUL_SDK
+GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
+APP_INI_DEPS = $(LIBXUL_DIST)/bin/platform.ini
+else
+GRE_MILESTONE = $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
+APP_INI_DEPS = $(topsrcdir)/config/milestone.txt
+endif
+
+APP_BUILDID := $(shell cat $(DEPTH)/config/buildid)
+APP_INI_DEPS += $(DEPTH)/config/buildid
+
+DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DAPP_BUILDID=$(APP_BUILDID)
+
+DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)"
+APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
+
+MOZ_SOURCE_STAMP ?= $(firstword $(shell hg -R $(topsrcdir) parent --template="{node|short}\n" 2>/dev/null))
+ifdef MOZ_SOURCE_STAMP
+DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
+endif
+
+_dollar=$$
+SOURCE_REPO := $(shell cd $(topsrcdir) && hg showconfig paths.default 2>/dev/null | head -n1 | sed -e "s/^ssh:/http:/" -e "s/\/$(_dollar)//" )
+ifdef SOURCE_REPO
+DEFINES += -DMOZ_SOURCE_REPO="$(SOURCE_REPO)"
+endif
+
+DEFINES += \
+  -DMOZ_APP_BASENAME="$(MOZ_APP_BASENAME)" \
+  -DMOZ_APP_VENDOR="$(MOZ_APP_VENDOR)" \
+  -DMOZ_APP_ID="$(MOZ_APP_ID)" \
+  $(NULL)
+
+ifdef MOZ_APP_PROFILE
+DEFINES += -DMOZ_APP_PROFILE="$(MOZ_APP_PROFILE)"
+endif
+
+ifdef MOZILLA_OFFICIAL
+DEFINES += -DMOZILLA_OFFICIAL
+endif
+
+ifdef MOZ_PROFILE_MIGRATOR
+DEFINES += -DMOZ_PROFILE_MIGRATOR
+endif
+
+ifdef MOZ_EXTENSION_MANAGER
+DEFINES += -DMOZ_EXTENSION_MANAGER
+endif
+
+endif
+
 include $(topsrcdir)/config/rules.mk
 
 # we install to _leaktest/
 TARGET_DEPTH = ..
 include $(srcdir)/automation-build.mk
 
 _LEAKTEST_DIR = $(DEPTH)/_leaktest
 GARBAGE_DIRS += $(_LEAKTEST_DIR)
@@ -94,16 +149,29 @@ GARBAGE_DIRS += $(_LEAKTEST_DIR)
 		$(topsrcdir)/build/pgo/blueprint/fancytype-screen.css \
 		$(NULL)
 
 leaktest.py: leaktest.py.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $^ > $@
 	chmod +x $@
 GARBAGE += leaktest.py
 
+ifdef MOZ_APP_BASENAME
+application.ini: application.ini.in $(APP_INI_DEPS)
+	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
+GARBAGE += application.ini
+
+ifdef MOZ_APP_STATIC_INI
+application.ini.h: appini_header.py application.ini 
+	$(PYTHON) $^ > $@
+export:: application.ini.h
+GARBAGE += application.ini.h
+endif
+endif
+
 libs:: $(_LEAKTEST_FILES)
 	$(INSTALL) $^ $(_LEAKTEST_DIR)
 
 ifdef MOZ_VALGRIND
 _VALGRIND_DIR = $(DEPTH)/_valgrind
 GARBAGE_DIRS += $(_VALGRIND_DIR)
 
 _VALGRIND_FILES = \
new file mode 100644
--- /dev/null
+++ b/build/appini_header.py
@@ -0,0 +1,86 @@
+# ***** 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 a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# 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 *****
+
+'''Parses a given application.ini file and outputs the corresponding
+   XULAppData structure as a C++ header file'''
+
+import ConfigParser
+import sys
+
+def main(file):
+    config = ConfigParser.RawConfigParser()
+    config.read(file)
+    flags = set()
+    try:
+        if config.getint('XRE', 'EnableExtensionManager') == 1:
+            flags.add('NS_XRE_ENABLE_EXTENSION_MANAGER')
+    except: pass
+    try:
+        if config.getint('XRE', 'EnableProfileMigrator') == 1:
+            flags.add('NS_XRE_ENABLE_PROFILE_MIGRATOR')
+    except: pass
+    try:
+        if config.getint('Crash Reporter', 'Enabled') == 1:
+            flags.add('NS_XRE_ENABLE_CRASH_REPORTER')
+    except: pass
+    appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s))
+    appdata['flags'] = ' | '.join(flags) if flags else '0'
+    appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL'
+
+    print '''#include "nsXULAppAPI.h"
+             static const nsXREAppData sAppData = {
+                 sizeof(nsXREAppData),
+                 NULL, // directory
+                 "%(App:vendor)s",
+                 "%(App:name)s",
+                 "%(App:version)s",
+                 "%(App:buildid)s",
+                 "%(App:id)s",
+                 NULL, // copyright
+                 %(flags)s,
+                 NULL, // xreDirectory
+                 "%(Gecko:minversion)s",
+                 "%(Gecko:maxversion)s",
+                 "%(Crash Reporter:serverurl)s",
+                 %(App:profile)s
+             };''' % appdata
+
+if __name__ == '__main__':
+    if len(sys.argv) != 1:
+        main(sys.argv[1])
+    else:
+        print >>sys.stderr, "Usage: %s /path/to/application.ini" % sys.argv[0]
rename from browser/app/application.ini
rename to build/application.ini.in
--- a/browser/app/application.ini
+++ b/build/application.ini.in
@@ -1,8 +1,14 @@
+#if MOZ_APP_STATIC_INI
+; This file is not used. If you modify it and want the application to use
+; your modifications, start with the "-app /path/to/application.ini"
+; argument.
+#endif
+#if 0
 ; ***** 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/
 ;
@@ -29,39 +35,43 @@
 ; 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 *****
-
+#endif
 #filter substitution
 [App]
 Vendor=@MOZ_APP_VENDOR@
 Name=@MOZ_APP_BASENAME@
-Version=@APP_VERSION@
+Version=@MOZ_APP_VERSION@
 #ifdef MOZ_APP_PROFILE
 Profile=@MOZ_APP_PROFILE@
 #endif
-BuildID=@GRE_BUILDID@
+BuildID=@APP_BUILDID@
 #ifdef MOZ_SOURCE_REPO
 SourceRepository=@MOZ_SOURCE_REPO@
 #endif
 #ifdef MOZ_SOURCE_STAMP
 SourceStamp=@MOZ_SOURCE_STAMP@
 #endif
-ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+ID=@MOZ_APP_ID@
 
 [Gecko]
 MinVersion=@GRE_MILESTONE@
 MaxVersion=@GRE_MILESTONE@
 
 [XRE]
+#ifdef MOZ_PROFILE_MIGRATOR
 EnableProfileMigrator=1
+#endif
+#ifdef MOZ_EXTENSION_MANAGER
 EnableExtensionManager=1
+#endif
 
 [Crash Reporter]
 #if MOZILLA_OFFICIAL
 Enabled=1
 #endif
-ServerURL=https://crash-reports.mozilla.com/submit?id=ec8030f7-c20a-464f-9b0e-13a3a9e97384&version=@APP_VERSION@&buildid=@GRE_BUILDID@
+ServerURL=https://crash-reports.mozilla.com/submit?id=@MOZ_APP_ID@&version=@MOZ_APP_VERSION@&buildid=@APP_BUILDID@
--- a/build/autoconf/make-makefile
+++ b/build/autoconf/make-makefile
@@ -1,9 +1,9 @@
-#! /usr/bin/env perl
+#!/usr/bin/env perl
 # ***** 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/
 #
@@ -11,149 +11,281 @@
 # 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.org code.
 #
 # The Initial Developer of the Original Code is
 # Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1999
+# Portions created by the Initial Developer are Copyright (C) 1999-2011
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
+#   Steve Lamm <slamm@netscape.com>
+#   Joey Armstrong <joey@mozilla.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 *****
 
-# make-makefiles - Quickly create Makefiles for subdirectories.
-#      Also, creates any needed subdirectories.
-#
-# usage: make-makefiles [ -t <topsrcdir> -p <print_topsrcdir> -d <depth> ] [ <subdir> | <subdir>/Makefile ] ...
+##----------------------------##
+##---] CORE/CPAN INCLUDES [---##
+##----------------------------##
+use strict;
+use warnings;
+use Getopt::Long;
 
-# Send comments, improvements, bugs to Steve Lamm (slamm@netscape.com).
+use Benchmark;
+use Cwd;
+use File::Basename;
+use File::Copy;
+use File::Path      qw{mkpath};
+
+##-------------------##
+##---]  EXPORTS  [---##
+##-------------------##
+our $VERSION = qw(2.0);
+
+##--------------------##
+##---]  INCLUDES  [---##
+##--------------------##
 
-#$debug = 1;
+##############################################################
+# pymake: special case path handling for windows cmd shell.
+#   if invoked by cmd.exe and msys-perl is in play
+#     $0 may contain a drive letter
+#     modules use-or-expect msys/unix paths
+#     adjust $0 => C:/foo => /c/foo so string tests and
+#     manipulation can by applied properly.
+##############################################################
+sub BEGIN
+{
+    if ($^O eq 'msys' && $ENV{PATH} =~ m!\w:/!)
+    {
+	$0 =~ s!^(\w):!/$1!;
+    }
+    eval 'use FindBin';
+    die $@ if ($@);
+}
+
+use lib $FindBin::Bin;
+use makemakefile;
 
-if ($^O eq 'msys') {
-  $pwdcmd = 'pwd -W';
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+my %argv;
+
+my $t0 = Benchmark->new();
+sub END
+{
+    if ($argv{bench})
+    {
+        my $t1 = Benchmark->new();
+        my $delta = timediff($t1, $t0);
+        print STDERR timestr($delta), "\n";
+    }
 }
-else {
-  $pwdcmd = 'pwd';
-}
+
+##----------------##
+##---]  MAIN  [---##
+##----------------##
+umask 0;
+
+my $debug = $argv{debug} || 0;
+
+my $pwdcmd = ($^O eq 'msys') ? 'pwd -W' : 'pwd';
 
 # Determine various tree path variables
 #
-($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
+my ($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
 
-$object_fullpath = `$pwdcmd`;
+my $object_fullpath = `$pwdcmd`; # Cwd::getcwd()
 chdir $depth;
-$object_root = `$pwdcmd`;
+my $object_root = `$pwdcmd`;  # Cwd::getcwd()
 chomp $object_fullpath;
 chomp $object_root;
 
 # $source_subdir is the path from the object root to where
 #    'make-makefile' was called. For example, if make-makefile was
 #    called from "mozilla/gfx/src", then $source_subdir would be
 #    "gfx/src/".
-$source_subdir = "$object_fullpath/";
+my $source_subdir = "$object_fullpath/";
 my $quoted_object_root = quotemeta($object_root);
 $source_subdir =~ s|^$quoted_object_root/||;
 
 # Prefix makefiles with $source_subdir so that paths
 # will be relative to the top of the object tree.
 #
-for $makefile (@makefiles) {
+my $makefile;
+for $makefile (@makefiles) { # dead code ?
   $makefile = "$source_subdir$makefile";
 }
 
-create_directories(@makefiles);
-
 # Find the path to the source directory based on how 'make-makefile'
 #  was invoked. The path is either relative to the object directory
 #  or an absolute path.
-$given_srcdir = find_srcdir($topsrcdir, $depth);
-$pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
+my $given_srcdir = find_srcdir($topsrcdir, $depth);
+my $pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
 
 if ($debug) {
   warn "object_fullpath = $object_fullpath\n";
   warn "object_root     = $object_root\n";
   warn "source_subdir   = $source_subdir\n";
   warn "makefiles       = @makefiles\n";
   warn "given_srcdir    = $given_srcdir\n";
 }
 
-@unhandled = update_makefiles($given_srcdir, $pgiven_srcdir, @makefiles);
+my @errors;
+my @unhandled = update_makefiles_legacy($given_srcdir, $pgiven_srcdir, @makefiles);
+push(@errors, $@) if ($@);
 
 run_config_status(@unhandled);
+push(@errors, $@) if ($@ && $argv{'no-warnings'});
+
+exit scalar(@errors);
 
 # end of Main
 ############################################################
 
-sub dirname {
- return $_[0] =~ /(.*)\/.*/ ? "$1" : '.';
-}
-
+###########################################################################
 # find_depth: Pull the value of DEPTH out of a Makefile (or Makefile.in)
+###########################################################################
 sub find_depth {
   my $depth = '';
   open(MAKEFILE, "<$_[0]") || die "Unable to open $_[0]: $!\n";
   while (<MAKEFILE>) {
     next unless /^DEPTH\s*=\s*(\..*)/;
     $depth = $1;
     last;
   }
   close MAKEFILE;
   return $depth;
 }
 
+###########################################################################
+## Intent: Parse command line arguments and assign values
+###########################################################################
 sub parse_arguments {
   my @args = @_;
-  my $depth = '';
-  my $topsrcdir = '';
-  my $ptopsrcdir;
   my @makefiles = ();
 
-  while (1) {
-    if ($args[0] eq '-d') {
-      $depth = $args[1];
-      shift @args; 
-      shift @args; 
-    } elsif ($args[0] eq '-t') {
-      $topsrcdir = $args[1];
-      shift @args; 
-      shift @args; 
-    } elsif ($args[0] eq '-p') {
-      $ptopsrcdir = $args[1];
-      shift @args;
-      shift @args;
-    } else {
-      last;
-    }
+  my @arglist = qw(badtokens! bench
+                   chdir=s
+                   debug
+                   depth|d=s
+                   enhanced
+                   obj=s top|t=s ptop|p=s
+                   src=s dst=s
+                   );
+  unless(GetOptions(\%argv, @arglist))
+  {
+      my $script = join('/', $FindBin::RealBin, $FindBin::Script);
+      system("perldoc $script </dev/null");
+      exit
+  }
+  @args = @ARGV;
+
+  my $topsrcdir = $argv{top} || '';
+  if (! $topsrcdir)
+  {
+      $topsrcdir = $argv{top} = getTopDir();
+  }
+
+  my $ptopsrcdir ||= $argv{ptop} || $topsrcdir || '';
+
+  ## Init --no- switch values
+  foreach my $var (qw(badtokens exclusions warnings))
+  {
+      $argv{"no-${var}"} = $argv{$var} || 0;
+  }
+  # Propogate parsed arguments for module use [--debug, --verbose]
+  while (my($k, $v) = each %argv)
+  {
+      $main::argv{$k} = $v;
+  }
+
+  if ($argv{chdir})
+  {
+      chdir $argv{chdir} || die "chdir $argv{chdir} failed: $!";
   }
 
-  if ($topsrcdir eq '') {
-    $topsrcdir = $0; # Figure out topsrcdir based on program name.
-    $topsrcdir =~ s|/?build/autoconf/.*$||;
+  ##############################################################
+  ## Arguments allowing make-makefile to be invoked from $topsrc
+  ##############################################################
+  if (!$argv{top} || !$argv{obj})
+  {
   }
-  if ($ptopsrcdir eq '') {
-    $ptopsrcdir = $topsrcdir;
+  ## Limit access to container makefiles for now
+  elsif ($argv{enhanced})
+  {
+      my @errors;
+
+      ## iterate over @ARGV to preserve original filename for 'unhandled'
+      my @files = map{ getRelPath($_) } @ARGV;
+
+      my $top = getTopDir();
+      my $obj = getObjDir();
+
+      mkdirr(map{ "$obj/$_" } @files);
+      push(@errors, $@) if ($@); # legacy behavior: do not exit with status
+
+      my $exclude = join('/', $FindBin::RealBin, $FindBin::Script);
+      $exclude .= '.excl'; # $argv{exclude}
+      my %exclude = getExclusions($exclude);
+      my @unhandled;
+      foreach my $relpath (@files)
+      {
+          my $rel = join('/', $relpath, 'Makefile.in');
+          my $mf = join('/', $top, $rel);
+          next if ($exclude{$rel});
+          print STDERR " ** relpath=[$relpath], mf=[$mf]\n" if ($main::argv{debug});
+
+          my $rc = updateMakefiles($relpath, {depth=>$depth, obj=>$obj, top=>$top});
+          if ($@)
+          {
+            push(@errors, $@);
+          }
+          elsif ($rc eq 'badtokens')
+          {
+            push(@unhandled, $mf);
+          }
+      }
+
+      run_config_status(@unhandled);
+      push(@errors, $@) if ($@ && $argv{'no-warnings'});
+      exit scalar(@errors);
   }
-  if ($depth eq '') {
+
+
+  my $depth = $argv{depth} || '';
+  if (! $depth)
+  {
+      foreach my $fyl (@args)
+      {
+          if (my $tmp = find_depth($fyl))
+          {
+              $depth = $tmp;
+              last;
+          }
+      }
+  }
+
+  if (! $depth) {
     # Use $(DEPTH) in the Makefile or Makefile.in to determine the depth
     if (-e "Makefile.in") {
       $depth = find_depth("Makefile.in");
     } elsif (-e "Makefile") {
       $depth = find_depth("Makefile");
     } elsif (-e "../Makefile") {
       $depth = "../".find_depth("../Makefile");
       $depth =~ s/\/\.$//;
@@ -161,44 +293,31 @@ sub parse_arguments {
       warn "Unable to determine depth (e.g. ../..) to root of objdir tree.\n";
       die  "No Makefile(.in) present. Try running with '-d <depth>'\n";
     }
   } 
 
   # Build the list of makefiles to generate
   #
   @makefiles = ();
-  my $makefile;
-  foreach $makefile (@args) {
-    $makefile =~ s/\.in$//;
-    $makefile =~ s/\/$//;
-    $makefile =~ /Makefile$/
-	or $makefile =~ /^\.\//
-	or $makefile .= "/Makefile";
+  while (@args)
+  {
+      next unless my $makefile = shift @args;
+      $makefile =~ s/\.in$//;
+      $makefile =~ s/\/$//;
+      $makefile =~ /Makefile$/
+        or $makefile =~ /^\.\//
+        or $makefile .= "/Makefile";
     push @makefiles, "$makefile";
   }
-  @makefiles = "Makefile" unless @args;
+  @makefiles = "Makefile" unless @makefiles;
 
   return ($topsrcdir, $ptopsrcdir, $depth, @makefiles);
 }
 
-
-# Create all the directories at once.
-#   This can be much faster than calling mkdir() for each one.
-sub create_directories {
-  my @makefiles = @_;
-  my @dirs = ();
-  my $ac_file;
-  foreach $ac_file (@makefiles) {
-    push @dirs, dirname($ac_file);
-  }
-  # Call mkdir with the directories sorted by subdir count (how many /'s)
-  system "mkdir -p ". join(' ', map("\"$_\"", @dirs)) if @dirs;
-}
-
 # Find the top of the source directory
 # (Assuming that the executable is in $top_srcdir/build/autoconf)
 sub find_srcdir {
   my ($ac_given_srcdir, $depth) = @_;
 
   if ($debug) {
     print "ac_given_srcdir = $ac_given_srcdir\n";
     print "depth           = $depth\n";
@@ -209,116 +328,151 @@ sub find_srcdir {
   }
   if ($debug) {
     print "ac_given_srcdir = $ac_given_srcdir\n";
   }
   $ac_given_srcdir = '.' if $ac_given_srcdir eq '';
   return $ac_given_srcdir;
 }
 
-# Output the makefiles.
-#
-sub update_makefiles {
-  my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
-  my @unhandled=();
+1;
+###########################################################################
+## perldoc 
+###########################################################################
+__END__
+
+=head1 NAME
+
+make-makefile - Generate a Makefile from a F<Makefile.in> template
+
+=head1 SYNOPSIS
+
+make-makefile [--top t] [--obj o] [--depth d] foo/bar/Makefile.in tans/fans/Makefile foo/bar
+
+=head1 DESCRIPTION
 
-  my $ac_file;
-  foreach $ac_file (@makefiles) {
-    my $ac_file_in    = "$ac_given_srcdir/${ac_file}.in";
-    my $ac_dir        = dirname($ac_file);
-    my $ac_dots       = '';
-    my $ac_dir_suffix = '';
-    my $srcdir        = '.';
-    my $top_srcdir    = '.';
+Given options and makefile path arguments determine path to the template
+F<Makefile.in> beneath a source directory and path to generated F<Makefile>
+beneath $MOZ_OBJDIR.  DEPTH from destination directory to the 'root' will
+also be determined.  F<Makefile.in> will be read in, template strings of the
+gorm @token@ will be replaced with derived values and a generated makefile
+will be written out as F<Makefile>.
+
+Makefile DEPTH= can be determined in a few different ways:
+  o The string C<DEPTH=../../..> may be embedded within F<Makefile.in>.
+  o Search parent directories for F<Makefile.in> and use it to assign the child.
+
+
+=head2 Option List
+
+=over 4
+
+=item --chdir
+
+Move to this directory before doing anything else
 
-    # Determine $srcdir and $top_srcdir
-    #
-    if ($ac_dir ne '.') {
-      $ac_dir_suffix = "/$ac_dir";
-      $ac_dir_suffix =~ s%^/\./%/%;
-      $ac_dots = $ac_dir_suffix;
-      # Remove .. components from the provided dir suffix, and
-      # also the forward path components they were reversing.
-      my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
-      while ($backtracks--) {
-        $ac_dots =~ s%/[^/]*%%;
-      }
-      $ac_dots =~ s%/[^/]*%../%g;
-    }
-    if ($ac_given_srcdir eq '.') {
-      if ($ac_dots ne '') {
-        $top_srcdir = $ac_dots;
-        $top_srcdir =~ s%/$%%;
-      }
-    } elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
-      $srcdir     = "$pac_given_srcdir$ac_dir_suffix";
-      $top_srcdir = "$pac_given_srcdir";
-    } else {
-      if ($debug) {
-      	print "ac_dots       = $ac_dots\n";
-	print "ac_dir_suffix = $ac_dir_suffix\n";
-      }
-      $srcdir     = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
-      $top_srcdir = "$ac_dots$ac_given_srcdir";
-    }
+=item -d, --depth
+
+Explicitly specify the relative path from directory containing Makefile.in
+to the top sandbox directory.  memory/makefile, DEPTH=../.., js/src/config, DEPTH=..
+
+=item --enhanced
+
+Use alternate/simplified path construction when options --top and --obj are
+passed.  This feature will be used by container makefiles to support makefile
+generation while cd'd into the sandbox top directory.
+
+=item -t, --top
+
+Path the root of a development sandbox.
+
+=item --obj
+
+Path to object directory where generated makefile will be written ($MOZ_OBJDIR).
+
+=item --ptop
+
+Print top source dir
+
+=back
+
+
+=head2 Options List DEBUG
+
+=over 4
+
+=item --bench
+
+Enable script benchmarking, report elapsed runtime.
+
+=item --debug
 
-    if ($debug) {
-      print "ac_dir     = $ac_dir\n";
-      print "ac_file    = $ac_file\n";
-      print "ac_file_in = $ac_file_in\n";
-      print "srcdir     = $srcdir\n";
-      print "top_srcdir = $top_srcdir\n";
-      print "cwd        = " . `$pwdcmd` . "\n";
-    }
+Enable script debug mode.
+
+=back
+
+
+=head2 Options List --NO-
+
+=over 4
+
+=item --no-badtokens (wip)
+
+Handle unexpanded @token@ makefile tokens as an error condition.
+Do not rely on system(config.status) to externally supply values.
+
+=item --no-excludes
+
+Ignore file entries on the exclusion list, generate everything.
 
-    # Copy the file and make substitutions.
-    #    @srcdir@     -> value of $srcdir
-    #    @top_srcdir@ -> value of $top_srcdir
-    #
-    if (-e $ac_file) {
-      next if -M _ < -M $ac_file_in;  # Next if Makefile is up-to-date.
-      warn "updating $ac_file\n";
-    } else {
-      warn "creating $ac_file\n";
-    }
+=item --no-warnings
+
+Warnings are handled as an error condition.
+
+=back
+
+
+=head2 Examples
 
-    open INFILE, "<$ac_file_in" or do {
-      warn "$0: Cannot read $ac_file_in: No such file or directory\n";
-      next;
-    };
-    open OUTFILE, ">$ac_file" or do {
-      warn "$0: Unable to create $ac_file\n";
-      next;
-    };
+=over 4
+
+=item * make-makefile -t /mozilla/nightly -d . memory/mozalloc
+
+cd $MOZ_OBJDIR;
+--top and --depth are explicitly set for generting memory/mozalloc/Makefile.
+
+=item * make-makefile -t /mozilla/nightly -d ../../../.. html5lib_tree_construction/Makefile
 
-    while (<INFILE>) {
-      #if (/\@[_a-zA-Z]*\@.*\@[_a-zA-Z]*\@/) {
-      #  #warn "Two defines on a line:$ac_file:$.:$_";
-      #  push @unhandled, $ac_file;
-      #  last;
-      #}
+cd $MOZ_OBJDIR/parser/htmlparser/tests/mochitest
+
+--top and --depth are explicitly set for generting a makefile from within
+a subdirectory of $MOZ_OBJDIR
+
+=item * make-makefile --top /mozilla/nightly --obj /mozilla/nightly/obj memory/mozalloc
 
-      s/\@srcdir\@/$srcdir/g;
-      s/\@top_srcdir\@/$top_srcdir/g;
+With --top and --obj explicitly set generate $MOZ_OBJDIR/memory/mozalloc/Makefile
+while sitting in the sandbox root.
+
+=back
+
+
+=head2 Work In Progress
+
+=over 4
 
-      if (/\@[_a-zA-Z]*\@/) {
-        #warn "Unknown variable:$ac_file:$.:$_";
-        push @unhandled, $ac_file;
-        last;
-      }
-      print OUTFILE;
-    }
-    close INFILE;
-    close OUTFILE;
-  }
-  return @unhandled;
-}
+=item --no-badtokens
+
+Fail on unexpanded @foo@ makefile tokens.  Any tokens that can be expanded
+directly by make-makefile will avoid config.status shell overhead.
+
+=item Depth from delta(--obj, --top)
 
-sub run_config_status {
-  my @unhandled = @_;
+If DEPTH= has not been embedded within a makefile the value could
+be set directly if --top and --obj are specified and the paths overlap.
+
+=back
+
 
-  # Run config.status with any unhandled files.
-  #
-  if (@unhandled) {
-    $ENV{CONFIG_FILES}= join ' ', @unhandled;
-    system "./config.status";
-  }
-}
+=head1 SEE ALSO
+
+L<config/rules.mk>
+
+=cut
new file mode 100644
--- /dev/null
+++ b/build/autoconf/make-makefile.excl
@@ -0,0 +1,5 @@
+###########################################################################
+## Intent: Exclusion list for container make builds
+###########################################################################
+
+# EOF
new file mode 100644
--- /dev/null
+++ b/build/autoconf/makemakefile.pm
@@ -0,0 +1,745 @@
+package makemakefile;
+
+# ***** 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.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999-2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Steve Lamm <slamm@netscape.com>
+#   Joey Armstrong <joey@mozilla.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 *****
+
+##----------------------------##
+##---] CORE/CPAN INCLUDES [---##
+##----------------------------##
+use strict;
+use warnings;
+# use feature 'state'; 5.10+ not available everywhere
+
+##-------------------##
+##---]  EXPORTS  [---##
+##-------------------##
+our $VERSION = qw(2.0);
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(dirname_legacy
+                 getConfig getDepth getRelPath getObjDir getTopDir mkdirr
+                 getExclusions
+                 run_config_status
+                 updateMakefiles
+                 update_makefiles_legacy
+                 );
+
+##--------------------##
+##---]  INCLUDES  [---##
+##--------------------##
+use Cwd;
+use Cwd     qw{abs_path};
+use FindBin;
+use File::Basename;
+use File::Copy;
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+umask 0;
+my $cwd = Cwd::abs_path('.');
+my %argv;
+
+
+###########################################################################
+## Intent: Helper function, retrieve contents of a file with error checking
+## -----------------------------------------------------------------------
+## Args:
+##   scalar   path to input file
+## Returns:
+##   array    contents of the given file
+##   $@       set on error
+###########################################################################
+sub cat
+{
+    my $fyl = shift || '';
+    $@ = '';
+    my @data;
+
+    local *FYL;
+    if (!open(FYL, $fyl))
+    {
+        $@ = "open($fyl) failed: $!";
+    }
+    else
+    {
+        @data = <FYL>;
+        close(FYL);
+    }
+    return @data;
+} # cat
+
+###########################################################################
+## Intent: Return directory path for a given argument
+## -----------------------------------------------------------------------
+## -----------------------------------------------------------------------
+## Todo:
+##   o Check if function can be replaced by File::Basename::dirname()
+###########################################################################
+sub dirname_legacy
+{
+    my $str = (@_ && defined($_[0])) ? shift : '';
+    return $str =~ /(.*)\/.*/ ? "$1" : '.';
+}
+
+###########################################################################
+## Intent: Given a list of makefile paths recursively create all
+##         directories between file and the root
+## -----------------------------------------------------------------------
+## Args:
+##   array   A list of makefiles
+##   fargs   Function arguments
+##     mode  Filesystem mode used for directory creation
+## Returns:
+##   $@      Set on error
+##   0       on success
+## -----------------------------------------------------------------------
+## Note:
+##   Reporting directory creation can be enabled by the --verbose
+##   command line argument.
+###########################################################################
+sub mkdirr
+{
+    my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
+    my $mode = $fargs{mode} || 0755;
+    my $verbose = $main::argv{verbose} || 0;
+    $@ = '' unless ($fargs{recursive});
+    $fargs{recursive} = 1;
+
+    my @errors;
+    push(@errors, $@) if ($@);
+    foreach my $path (@_)
+    {
+        (my $dir = $path) =~ s%/?Makefile[^/]*$%%o;
+        next unless (length($dir));
+        next if (-e $dir);
+        mkdirr( dirname($dir), \%fargs);
+        eval{ File::Path::mkpath($dir, $verbose, 0755); };
+        push(@errors, $@) if ($@);
+    }
+    $@ = join("\n", @errors);
+    return $@ ? 0 : 1;
+} # mkdirr
+
+###########################################################################
+## Intent: Read in configure values and return a hash of key/value pairs
+## -----------------------------------------------------------------------
+## Args:
+##   fargs  Function arguments
+##     reset   clear value storage and repopulate
+## Returns:
+##   hash  configure data to use for makefile substitutions
+## -----------------------------------------------------------------------
+## Todo: wrapper for reading config* and run_config_status
+###########################################################################
+my %_CONFIG_; # todo: state %config; w/5.10
+sub getConfig
+{
+    my %fargs = (@_ && ref($_[$#_]) eq 'HASH') ? %{ (pop) } : ();
+    if ($fargs{reset})
+    {
+        %_CONFIG_ = ();
+        shift;
+    }
+
+    #my $ac_file_in    = "$ac_given_srcdir/${ac_file}.in";
+    #my $ac_dir        = dirname_legacy($ac_file);
+    #my $ac_dots       = '';
+    #my $ac_dir_suffix = '';
+    #my $srcdir        = '.';
+    #my $top_srcdir    = '.';
+    unless (%_CONFIG_)
+    {
+        while (@_)
+        {
+            my ($k, $v) = splice(@_, 0, 2);
+            $_CONFIG_{$k} = $v;
+        }
+    }
+
+    return %_CONFIG_;
+} # getConfig
+
+###########################################################################
+## Intent: Determine path depth between leaf and root directory.
+##   o DEPTH= may be set by makefile content
+##   o DEPTH= may be set by Makefile in a parent
+##   o Manually determine by relpath form leaf to sandbox top
+## -----------------------------------------------------------------------
+## Args:
+##   scalar  Path to makefile or directory to determine DEPTH for
+## Returns:
+##   scalar  Relative path from leaf to root directory
+## -----------------------------------------------------------------------
+###########################################################################
+sub getDepth($)
+{
+    my $fyl = shift || '';
+
+    my @path = split(m%/%o, $fyl);
+    pop(@path) if ('Makefile' eq substr($path[$#path], 0, 8));
+    my $depth;
+    my @depth;
+
+    my $top = getTopDir();
+    my @top = split(m%/%o, $top);
+    my @pathNoTop = @path;
+    splice(@pathNoTop, 0, scalar(@top));
+
+    SEARCH:
+    while (@path)
+    {
+        ## Search for a file containing DEPTH=../..
+        foreach my $fyl ( qw{Makefile.in Makefile} )
+        {
+            my $path = join('/', @path, $fyl);
+            local *FYL;
+            if (!open(FYL, $path)) {} # NOP
+            elsif (my @tmp = map{ /^\s*DEPTH\s*=\s*([\.\/]+)/o ? $1 : () } <FYL>)
+            {
+                $depth = join('/', @depth, shift @tmp);
+                last SEARCH;
+            }
+            close(FYL);
+        }
+        pop @path;
+        pop @pathNoTop;
+
+        if (0 == scalar(@pathNoTop))
+        {
+            $depth = join('/', @depth);
+            last;
+        }
+        
+        ## Construct path manually
+        push(@depth, '..');
+    }
+    return $depth;
+} # getDepth
+
+###########################################################################
+## Intent: Read in the exclusion file
+###########################################################################
+sub getExclusions
+{
+    my $file = shift || '';
+    
+    return () if ($main::argv{'no-exclusions'});
+
+    my %exclude;
+    if ($file)
+    {
+        my @data = cat($file);
+        foreach (@data)
+        {
+            next unless ($_);
+            next if (/^\s*\#/o);
+            next unless (m%/%);
+            chomp;
+            $exclude{$_}++;
+        }
+    }
+    return %exclude;
+} # getExclusions
+
+###########################################################################
+## Intent: Given the path to a makefile beneath either src or obj
+##         derive the relative path prefix between makefile and root.
+###########################################################################
+sub getRelPath
+{
+    my $path0 =  shift;
+    my $abspath;
+
+    # Determine type and orientation
+    my $name = basename($path0);
+    my $haveMF = ($name eq 'Makefile.in') ? 1
+        : ($name eq 'Makefile') ? -1
+        : 0
+        ;
+
+    ####################################################
+    ## Prep work: form a relative path with ../ removed
+    ####################################################
+    my $top = getTopDir();
+    my $obj = getObjDir();
+    ## If the same Makefile will be created alongside Makefile.in
+    my $topQM = quotemeta($top);
+    my $objQM = quotemeta($obj);
+
+    if ('..' eq substr($path0, 0, 2))
+    {
+        my @cwd = split(m%/%, $cwd);
+        my @pth = split(m%/%, $path0);
+        while (@pth && $pth[0] eq '..')
+        {
+            pop(@cwd);
+            shift @pth;
+        }
+        $path0 = join('/', @cwd, @pth);
+        $abspath = $path0;
+    }
+
+    if ('/' eq substr($path0, 0, 1))
+    {
+        $path0 =~ s%^$objQM\/?%%;
+        $path0 =~ s%^$topQM\/?%%;
+    }
+
+    #######################################################################
+    ## Build a list of directories to search.  Input source will be one
+    ## of path to Makefile.in, path to Makefile, directory, file within
+    ## a directory or relative path from cwd.
+    #######################################################################
+    my @subdirs;
+    my $path = (0 == $haveMF) ? $path0 : dirname($path0);
+    push(@subdirs, $path); # containing directory
+    push(@subdirs, dirname($path)) if (0 == $haveMF && -f $path); # Arg is file within a directory
+    push(@subdirs, $cwd);  # relative to pwd
+
+    # obj - path to generated makefile
+    # top - path to Makefile.in source template
+    my @prefixes = ('/' ne substr($path0, 0, 1))
+        ? (&getTopDir, &getObjDir)
+        : ()
+        ;
+
+  ON_SAFARI:
+    for my $prefix (@prefixes)
+    {
+        next unless ($prefix); # no command line not passed
+        foreach my $subdir (@subdirs)
+        {
+            foreach my $mf ('Makefile.in', 'Makefile')
+            {
+                my $path = join('/', $prefix, $subdir, $mf);
+                if (-e $path)
+                {
+                    $name = $mf;
+                    $haveMF = ($mf eq 'Makefile.in') ? 1 : -1;
+                    $abspath = $path;
+                    last ON_SAFARI;
+                }
+            }
+        }
+    }
+
+    #######################################################################
+    ## Generated makefile does not yet exist or path is invalid.
+    ## Should this conditon be handled to detect non-existent Makefile.in:
+    ##   Makefile.am => Makefile.in => Makefile but Makefile.in
+    #######################################################################
+    if (!$abspath && -1 == $haveMF && $obj)
+    {
+        $abspath = ('/' eq substr($path0, 0, 1)) 
+            ? $path0
+            : join('/', $obj, $path0)
+            ;
+    }
+
+    ########################################################
+    ## If --top and/or --obj specified extract relative path
+    ########################################################
+    my $relpath;
+    if (! $abspath)
+    {
+        # Error, fall through
+    }
+    elsif (1 == $haveMF) # Makefile.in
+    {
+        ## err w/o --top
+        (my $tmp = $abspath) =~ s%^$topQM/?%%;
+        $relpath = dirname($tmp) unless ($tmp eq $abspath);
+    }
+    elsif (-1 == $haveMF) # Makefile
+    {
+        ## err w/o --obj
+        (my $tmp = $abspath) =~ s%^$objQM/?%%;
+        $relpath = dirname($tmp) unless ($tmp eq $abspath);
+    }
+
+    $relpath ||= '';
+    $relpath =~ s%/./%/%og; # filter ./
+
+    $@ = ($relpath) ? '' : "ERROR($path0): Unable to locate sources";
+    return $relpath || '';
+} # getRelPath
+
+###########################################################################
+## Intent: Determine sandbox root from script startup directory
+## -----------------------------------------------------------------------
+## Args:
+##    _set_    optional, if passed use the given value as path
+##    _reset_  clear cached directory path to reassign
+## Returns:
+##   scalar - absolute path to the sandbox root directory
+## -----------------------------------------------------------------------
+###########################################################################
+my $gtd_dir;
+sub getTopDir
+{
+    if (@_) # testing override
+    {
+        $gtd_dir = abs_path($_[1] || '.') if ($_[0] eq '_set_');
+        $gtd_dir = ''    if ($_[0] eq '_reset_');
+    }
+
+    unless ($gtd_dir)
+    {
+        ## Set by command line
+        if ($main::argv{top})
+        {
+            $gtd_dir = $main::argv{top};
+        }
+        else
+        {
+            my $path = abs_path($FindBin::RealBin);
+            my @path = split(m%/%o, $path);
+            ## --2 memory/mozalloc/Makefile.in
+            ## --3 was this for FindBin::Script ?
+            splice(@path, -2);
+            $gtd_dir = join('/', @path);
+        }
+    }
+    return $gtd_dir;
+} # getTopDir
+
+###########################################################################
+## Intent: Determine path to MOZ_OBJDIR/object directory
+## -----------------------------------------------------------------------
+## Args:
+##   _set_    optional testing arg, if passed re-compute cached value
+## Returns:
+##   scalar - absolute path to the sandbox object directory
+## -----------------------------------------------------------------------
+###########################################################################
+my $god_dir;
+sub getObjDir
+{
+    if (@_) # testing override
+    {
+        if ($_[0] eq '_reset_')
+        {
+            $god_dir = '';
+            shift;
+        }
+        elsif ($_[0] eq '_set_')
+        {
+            shift;
+            my $path = $_[0] || '.';
+            $god_dir = abs_path($path);
+            shift;
+        }
+    }
+
+    ## extract $obj from given path
+    unless ($god_dir)
+    {
+        if ($main::argv{obj})
+        {
+            $god_dir = $main::argv{obj};
+        }
+        elsif (@_ && 'Makefile' eq substr($_, -8))
+        {
+            $god_dir = abs_path(shift);
+        }
+        else # assume we are sitting in moz_objdir
+        {
+            $god_dir = abs_path('.');
+        }
+    }
+
+    return $god_dir;
+} # getObjDir
+
+###########################################################################
+## Intent: Generate Makefile from a given Makefile.in template
+## -----------------------------------------------------------------------
+## Args:
+##   scalar  Relative path to a directory containing a makefile
+##   fargs   Hash ref of function arguments.
+##     obj     Absolute path to MOZ_OBJ/a destination directory
+##     top     Absolute path to the sandbox root
+## Returns:
+##    $@     Set on error
+##    scalar
+##      1     True if the makefile was updated
+##      0     Otherwise
+##      badtokens - If the makefile contains unexpandable @token@ strings
+## -----------------------------------------------------------------------
+###########################################################################
+sub updateMakefiles
+{
+    my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
+    local $_;
+    $@ = '';
+
+    my $top = $fargs{top};
+    my $obj = $fargs{obj};
+
+    my $relpath = shift || '';
+    my $src = join('/',  $top, $relpath, 'Makefile.in');
+    my $depth = getDepth($src);
+
+    my @src = cat($src);
+    return 0 if ($@);
+
+    my $dst = join('/', $obj, $relpath, 'Makefile');
+    my @dst = cat($dst);
+    $@ = '';
+
+    my $dstD = dirname($dst);
+    mkdirr($dstD);
+    return 0 if ($@);
+
+    my %data =
+        ( getConfig(),
+          depth      => $depth,
+          srcdir     => join('/', $top, $relpath),
+          top_srcdir => $top,
+        );
+
+    my $line = 0;
+    my @data;
+    while (scalar @src)
+    {
+        $line++;
+        $_ = shift(@src);
+
+        ## Expand embedded @foo@
+        while (/\@[^\@\s\$]+\@/go)
+        {
+            my $end = pos($_);
+            my $val = $&;
+            my $len = length($val);
+            $val =~ s/^\@\s*//o;
+            $val =~ s/\s*\@$//o;
+
+            ## Identify expansions to see if we can avoid shell overhead
+            if (!defined $data{$val} && !$argv{'no-badtokens'})
+            {
+                if (1) # warnings
+                {
+                    print STDERR "WARNING: token $val not defined\n";
+                    print STDERR "   line $line, src: $src\n";
+                }
+                return 'badtokens';
+            }
+
+            # Insert $(error txt) makefile macros for invalid tokens
+            my $val1 = defined($data{$val})
+                ? $data{$val}
+                : "\$(error $FindBin::Script: variable ${val} is undefined)"
+                ;
+            substr($_, ($end-$len), $len, $val1);
+        }
+        push(@data, $_);
+    }
+
+    if (("@data" eq "@dst") && scalar(@data))
+    {
+        print "Skipping up2date makefile: $dst\n" if ($argv{verbose});
+    }
+    else
+    {
+        my $action = (scalar @dst) ? 'Updating' : 'Creating';
+        print "$action makefile: $dst\n";
+
+        my $tmp = join('.', $dst, "tmp_$$");
+        if (!open(FYL, "> $tmp"))
+        {
+            $@ = "open($tmp) failed: $!";
+        }
+        else
+        {
+            print FYL @data;
+            close(FYL);
+
+            ## Install the new makefile
+            File::Copy::move($tmp, $dst)
+                || ($@ = "move($tmp, $dst) failed: $!");
+        }
+    }
+
+    return $@ ? 0 : 1;
+} # updateMakefiles
+
+# Output the makefiles.
+#
+sub update_makefiles_legacy {
+  my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
+  my $debug = $main::argv{debug} || 0;
+  my $pwdcmd = ($^O eq 'msys') ? 'pwd -W' : 'pwd';
+  my @unhandled=();
+
+  my @warn;
+
+  my $ac_file;
+  foreach $ac_file (@makefiles) {
+    my $ac_file_in    = "$ac_given_srcdir/${ac_file}.in";
+    my $ac_dir        = dirname_legacy($ac_file);
+    my $ac_dots       = '';
+    my $ac_dir_suffix = '';
+    my $srcdir        = '.';
+    my $top_srcdir    = '.';
+
+    # Determine $srcdir and $top_srcdir
+    #
+    if ($ac_dir ne '.') {
+      $ac_dir_suffix = "/$ac_dir";
+      $ac_dir_suffix =~ s%^/\./%/%;
+      $ac_dots = $ac_dir_suffix;
+      # Remove .. components from the provided dir suffix, and
+      # also the forward path components they were reversing.
+      my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
+      while ($backtracks--) {
+        $ac_dots =~ s%/[^/]*%%;
+      }
+      $ac_dots =~ s%/[^/]*%../%g;
+    }
+    if ($ac_given_srcdir eq '.') {
+      if ($ac_dots ne '') {
+        $top_srcdir = $ac_dots;
+        $top_srcdir =~ s%/$%%;
+      }
+    } elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
+      $srcdir     = "$pac_given_srcdir$ac_dir_suffix";
+      $top_srcdir = "$pac_given_srcdir";
+    } else {
+      if ($debug) {
+              print "ac_dots       = $ac_dots\n";
+        print "ac_dir_suffix = $ac_dir_suffix\n";
+      }
+      $srcdir     = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
+      $top_srcdir = "$ac_dots$ac_given_srcdir";
+    }
+
+    if ($debug) {
+      print "ac_dir     = $ac_dir\n";
+      print "ac_file    = $ac_file\n";
+      print "ac_file_in = $ac_file_in\n";
+      print "srcdir     = $srcdir\n";
+      print "top_srcdir = $top_srcdir\n";
+      print "cwd        = " . `$pwdcmd` . "\n";
+    }
+
+    # Copy the file and make substitutions.
+    #    @srcdir@     -> value of $srcdir
+    #    @top_srcdir@ -> value of $top_srcdir
+    #
+    if (-e $ac_file) {
+      next if -M _ < -M $ac_file_in;  # Next if Makefile is up-to-date.
+      warn "updating $ac_file\n";
+    } else {
+      warn "creating $ac_file\n";
+    }
+
+    mkdirr(dirname($ac_file));
+
+    open INFILE, "<$ac_file_in" or do {
+      warn "$0: Cannot read $ac_file_in: No such file or directory\n";
+      next;
+    };
+    open OUTFILE, ">$ac_file" or do {
+      warn "$0: Unable to create $ac_file\n";
+      next;
+    };
+
+    while (<INFILE>) {
+      s/\@srcdir\@/$srcdir/g;
+      s/\@top_srcdir\@/$top_srcdir/g;
+
+      if (/\@[_a-zA-Z]*\@/) {
+        #warn "Unknown variable:$ac_file:$.:$_";
+        push @unhandled, $ac_file;
+        last;
+      }
+      print OUTFILE;
+    }
+    close INFILE;
+    close OUTFILE;
+  }
+  return @unhandled;
+} # update_makefiles_legacy
+
+###########################################################################
+## Intent: Invoke config.status for unknown makefiles to create
+##         directory hierarchy for the tree.
+## -----------------------------------------------------------------------
+## Args:
+##   array   an optional list of makefiles to process
+## Returns:
+##   0    on success
+##   $#   set on error
+## -----------------------------------------------------------------------
+## Note: Is this function needed anymore ?  Undefined tokens should fail
+##   at time of expansion rather than having to source config.status.
+##   Also config.status could be parsed to define values and avoide the
+##   shell overhead altogether.
+###########################################################################
+sub run_config_status {
+  my @unhandled = @_;
+
+  # Run config.status with any unhandled files.
+  #
+  my @errors;
+  if (@unhandled) {
+    local $ENV{CONFIG_FILES}= join ' ', @unhandled;
+
+    my $conf = 'config.status';
+    if (! -e $conf) # legacy behavior, warn rather than err
+    {
+        my $cwd = cwd();
+        my $err = "$FindBin::Script ERROR: Config file $conf does not exist, cwd=$cwd";
+        push(@errors, $err);
+    }
+    elsif (0 != system("./config.status"))
+    {
+        my $cwd = cwd();
+        push(@errors, "config.status failed \$?=$?, \$!=$!, cwd: $cwd");
+    }
+  }
+  $@ = join("\n", @errors);
+
+  ## Legacy behavior: config.status problems are not fatal {yet}.
+  ## Display warning since caller will not be calling die.
+  warn $@ if ($@ && $argv{'no-warnings'});
+  return $@ ? 1 : 0;
+}
+
+1;
new file mode 100644
--- /dev/null
+++ b/build/autoconf/test/Makefile.in
@@ -0,0 +1,94 @@
+# -*- makefile -*-
+#
+# ***** 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.org code.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Joey Armstrong <joey@mozilla.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
+
+##################################################
+## Gather a list of tests, generate timestamp deps
+##################################################
+TS=.ts
+ifneq (,$(findstring check,$(MAKECMDGOALS)))
+          allsrc = $(wildcard $(srcdir)/*)
+       tests2run = $(notdir $(filter %.tpl,$(allsrc)))
+       tests2run += $(notdir $(filter %.tpm,$(allsrc)))
+  check_targets += $(addprefix $(TS)/,$(tests2run))
+endif
+
+all_nop: # export, libs and tools are not needed
+
+check:: $(TS) $(check_targets)
+
+#############################################
+# Only invoke tests when sources have changed
+#############################################
+$(TS)/%: $(srcdir)/%
+	$(PERL) $(srcdir)/runtest $<
+	@touch $@
+
+parent = $(patsubst %/,%,$(dir $(srcdir)))
+$(TS)/make-makefile.tpl: \
+  $(srcdir)/make-makefile.tpl\
+  $(parent)/makemakefile.pm\
+  $(NULL)
+	$(PERL) $(srcdir)/runtest $<
+	@touch $@
+
+$(TS)/makemakefile.tpm: \
+  $(srcdir)/makemakefile.tpm \
+  $(parent)/makemakefile.pm \
+  $(NULL)
+	$(PERL) $(srcdir)/runtest $<
+	@touch $@
+
+#####################################################
+## Extra dep needed to synchronize parallel execution
+#####################################################
+$(TS): $(TS)/.done
+$(TS)/.done:
+	$(MKDIR) -p $(dir $@)
+	touch $@
+
+GARBAGE_DIRS += $(TS)
+
+# EOF
new file mode 100644
--- /dev/null
+++ b/build/autoconf/test/data/mf.notokens
@@ -0,0 +1,4 @@
+jsautocfg.h: jscpucfg$(HOST_BIN_SUFFIX)
+        @$(RM) $@ jsautocfg.tmp
+        ./jscpucfg > jsautocfg.tmp
+        mv jsautocfg.tmp $@
new file mode 100644
--- /dev/null
+++ b/build/autoconf/test/data/mf.notokens.exp
@@ -0,0 +1,4 @@
+jsautocfg.h: jscpucfg$(HOST_BIN_SUFFIX)
+        @$(RM) $@ jsautocfg.tmp
+        ./jscpucfg > jsautocfg.tmp
+        mv jsautocfg.tmp $@
new file mode 100644
--- /dev/null
+++ b/build/autoconf/test/make-makefile.excl
@@ -0,0 +1,8 @@
+###########################################################################
+## Intent: Exclusion list for container make builds
+###########################################################################
+
+/dev/null
+/foo/bar
+/a/b/c
+/a/b/d
new file mode 100644
--- /dev/null
+++ b/build/autoconf/test/make-makefile.tpl
@@ -0,0 +1,436 @@
+#!/usr/bin/env perl
+###########################################################################
+## Intent: Unit test to verify make-makefile.tpl
+###########################################################################
+
+##----------------------------##
+##---] CORE/CPAN INCLUDES [---##
+##----------------------------##
+use strict;
+use warnings;
+#use feature 'state';  # 5.10+ not installed everywhere
+use Getopt::Long;
+
+use Cwd;
+use Cwd         qw{abs_path};
+use File::Basename;
+use File::Copy;
+use File::Path;
+use File::Temp  qw{ tempdir };
+
+use Test;
+sub BEGIN { plan tests => 4 };
+my @workdirs;
+sub END { system("/bin/rm -fr @workdirs"); }  # cleanup behind interrupts
+
+##-------------------##
+##---]  EXPORTS  [---##
+##-------------------##
+use FindBin;
+our $VERSION = qw(1.0);
+
+##------------------##
+##---] INCLUDES [---##
+##------------------##
+use FindBin;
+use lib "$FindBin::RealBin/..";
+use makemakefile;
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+my %argv;
+
+###########################################################################
+## Intent: Create a temp sandbox populated with sources
+## -----------------------------------------------------------------------
+## Args:
+##   array    a list of file paths to copy
+## Returns:
+##     $@     set on error
+##   scalar   path to scratch sandbox
+## -----------------------------------------------------------------------
+###########################################################################
+my $root; # state $root not available
+sub createSandbox
+{
+    my @errors;
+
+    unless ($root)
+    {
+        my @tmp = split(m%/%, $FindBin::RealBin);
+        splice(@tmp, -3);
+        $root = join('/', @tmp);
+    }
+
+    my $work = tempdir();
+    push(@workdirs, $work);
+    my @dirs = map{ join('/', $work, dirname($_)) } @_;
+    mkdirr(@dirs);
+    push(@errors, "createSandbox: $@") if ($@);
+
+    foreach (@_)
+    {
+        ## Copy sources into the temp source directory
+        my $src = join('/', $root, $_);
+        my $dst = join('/', $work, $_);
+        unless (copy($src, $dst))
+        {
+            push(@errors, "copy($src, $dst) failed: $!");
+        }
+    }
+    print STDERR "createSandbox: $work\n" if ($main::argv{debug});
+    $@ = join('', map{ "$_\n" } @errors);
+    $work;
+} # createSandbox
+
+###########################################################################
+## Intent: wrapper to run the make-makefile command.
+## -----------------------------------------------------------------------
+## Args:
+##   array  command line arguments passed to make-makefile
+## Returns:
+##    array  command output
+##    $@     set by shell exit status, empty string on success
+##    $?     command shell exit status
+###########################################################################
+my $mm; # state $mm not available
+sub makemakefile
+{
+    my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
+    $mm ||= join('/', dirname($FindBin::Bin), 'make-makefile'); # cmd in parent of test/
+    my $cmd = join(' ', $mm, @_);
+    print "RUNNING: $cmd\n" if ($fargs{debug});
+    my @out = `$cmd 2>&1`;
+    print STDERR map{ "out> $_" } @out if ($argv{verbose});
+    $@ = (0 == $?) ? '' : "Command failed: $cmd\n@out";
+    @out;
+} # makemakefile
+
+###########################################################################
+## Intent: Helper function, display the contents of a given sandbox
+## -----------------------------------------------------------------------
+## Args:
+##   scalar   Path to sandbox
+## Returns:
+##   none
+## -----------------------------------------------------------------------
+###########################################################################
+sub find_ls
+{
+    my $path = shift || '';
+
+    # Assuming dot contributes to cryptic problems
+    die "find_ls: a path is required" unless ($path);
+
+    my $cmd = "find $path -ls";
+    print "\nRunning: $cmd\n";
+    print '=' x 75, "\n";
+    print `$cmd`;
+} # myls
+
+###########################################################################
+## Intent: Verify make-makefile is able to digest paths and generate
+##         makefiles when object directory is a child of top.
+###########################################################################
+sub check_makemakefile
+{
+    my $work = createSandbox
+        (
+         'memory/mozalloc/Makefile.in',
+         'toolkit/system/windowsproxy/Makefile.in',
+         'toolkit/crashreporter/google-breakpad/src/client/Makefile.in',
+        );
+
+
+    my $workdir = createSandbox();
+    my $top = $workdir;
+    chdir $top;
+
+    my $objA = 'obj-arch-dir';
+    my $obj = join('/', $top, $objA);
+
+    # getTopDir()
+    local $main::argv{top} = $work;
+    local $main::argv{obj} = $obj;
+    getObjDir('_reset_');
+
+    my @root = split(m%/%, $FindBin::RealBin);
+    splice(@root, -3);
+    my $root = join('/', @root);
+    my @args =
+        (
+
+         [
+          banner => "--top and --obj are impled, generate Makefile",
+             rel => 'memory/mozalloc',
+             cmd => join(' ',
+                         '--top', $top,
+                         '--obj', $obj,
+                         'memory/mozalloc/Makefile',
+                         ),
+         ],
+
+         [
+          banner => "--top and abs(obj) passed",
+             rel => "toolkit/system/windowsproxy",
+             cmd => join(' ',
+                         '--top', $top,
+                         "$obj/toolkit/system/windowsproxy/Makefile",
+                         ),
+             exp => "$obj/toolkit/system/windowsproxy/Makefile",
+            skip => 1, #
+         ],
+
+
+         [
+          banner => "--obj and abs(top) passed",
+             rel => "toolkit/crashreporter/google-breakpad/src/client",
+             cmd => join(' ',
+                         '--obj', $obj,
+                         "$top/toolkit/crashreporter/google-breakpad/src/client/Makefile.in",
+                         ),
+             exp => "$top/toolkit/crashreporter/google-breakpad/src/client/Makefile.in",
+          skip => 1, #
+         ],
+
+         );
+
+    foreach (@args)
+    {
+        my %rec = @{ $_ };
+        next if ($rec{skip});
+        next unless ($rec{rel});
+
+        my $srcR = join('/', $top, $rec{rel});
+        my $dstR = join('/', $obj, $rec{rel});
+
+        my $src = join('/', $top, $rec{rel}, 'Makefile.in');
+        my $dst = join('/', $obj, $rec{rel}, 'Makefile');
+
+        # Use distinct sources to avoid cleanup overhead between tests
+        die "Test source already used: $dstR" if (-d $dstR);
+
+        ## Copy sources into the temp source directory
+        my $rootR = join('/', $root, $rec{rel});
+        my $rootS = join('/', $root, $rec{rel}, 'Makefile.in');
+        File::Path::mkpath($srcR, 0, 0700);
+        copy($rootS, $src) or die "copy($rootS, $src) failed: $!";
+
+        die "source does not exist: $src" unless (-e $src);
+
+        ######################
+        ## Generate and verify
+        ######################
+        print STDERR "RUNNING: $rec{banner}\n" if ($argv{debug});
+        my @errs;
+        makemakefile('--enhanced', $rec{cmd}, {verbose=>1});
+        if ($@)
+        {
+            push(@errs, "\$@ should not be set: $@\n");
+        }
+        elsif (! -e $dst)
+        {
+            push(@errs, "Generated makefile does not exist: $dst, banner: $rec{banner}\n");
+        }
+
+        ok(scalar(@errs), 0, "Errors detected:\n" . join("    $_", @errs));
+        find_ls($top) if (@errs);
+    }
+
+} # check_makemakefile
+
+###########################################################################
+## Intent: Verify make-makefile is able to digest paths and generate
+##         makefiles when top/MOZ_OBJDIR are not parent/child directories
+## ---------------------------------------------------------------------------
+## Args:
+##   none
+## Returns:
+##   none
+## ---------------------------------------------------------------------------
+###########################################################################
+sub check_makemakefile_distinct
+{
+    my $workdir = createSandbox();
+#    my $workdir = tempdir();
+
+    ###############################################
+    ## Now update when top/obj are not parent/child
+    ###############################################
+    my $top = join('/', $workdir, 'top');
+    my $obj = join('/', $workdir, 'obj');
+
+    $main::argv{top} = $top;
+    $main::argv{obj} = $obj;  # test afterward, using undef ?
+
+    my @sbxroot = split(m%/%, $FindBin::RealBin);
+    splice(@sbxroot, -2);
+    my $sbxroot = join('/', @sbxroot);
+
+    ## Copy in a makefile template to to convert
+    File::Path::mkpath(["$top/memory/mozalloc"], 0, 0700);
+    copy("$sbxroot/memory/mozalloc/Makefile.in", "$top/memory/mozalloc/Makefile.in");
+
+
+    # work/memory/mozalloc/Makefile.in
+
+    my @args =
+        (
+         [
+          banner => '--top and --obj are distinct [1]',
+             cmd => "--obj $obj memory/mozalloc/Makefile",
+             exp => "$obj/memory/mozalloc/Makefile",
+         ],
+
+         [
+          banner => "--top and --obj are distinct [2]",
+             cmd => "--top $top memory/mozalloc/Makefile.in",
+             exp => "$obj/memory/mozalloc/Makefile",
+            skip => 1,  # test problem: top != obj
+         ],
+
+         [
+          banner => "--top and --obj are distinct [3]",
+             cmd => join(' ',
+                         "--top $top",
+                         "--obj $obj",
+                         "memory/mozalloc/Makefile.in",
+                         ),
+             exp => "$obj/memory/mozalloc/Makefile",
+            skip => 1,  # test problem: top != obj
+         ],
+        );
+
+
+    foreach (@args)
+    {
+        my %rec = @{ $_ };
+        print STDERR "banner: $rec{banner}\n" if ($argv{debug});
+        next if $rec{skip};
+
+        unlink $rec{exp};
+        makemakefile('--enhanced', $rec{cmd});
+
+        my @errs;
+        if ($@)
+        {
+            push(@errs, "\$@ should not be set: $@\n");
+        }
+        elsif (! -e $rec{exp})
+        {
+            push(@errs, "Makefile does not exist: $rec{exp}\n");
+        }
+        ok(scalar(@errs), 0, "Errors detected:\n" . join("    $_", @errs));
+    }
+
+} # check_makemakefile_distinct
+
+###########################################################################
+## Intent: Verify legacy behavior, invoke make-makefile when cwd is
+##         a subdirectory beneath MOZ_OBJDIR.
+## -----------------------------------------------------------------------
+## Args:
+##   none
+## Returns:
+##   none
+## -----------------------------------------------------------------------
+###########################################################################
+sub check_makemakefile_legacy
+{
+    my $work = createSandbox
+        (
+         'memory/mozalloc/Makefile.in',
+         'parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile.in',
+        );
+
+    my $obj = join('/', $work, 'obj');
+    mkdir $obj;
+
+    my @args =
+        (
+         {
+             banner => '-t path -d dot',
+                cwd => $obj,
+                cmd => "-t $work -d . memory/mozalloc/Makefile",
+                exp => "$obj/memory/mozalloc/Makefile",
+               skip => 0,
+         },
+         
+         {
+             banner => '-t path -d relpath',
+                cwd => join('/', $obj, 'parser/htmlparser/tests/mochitest'),
+                cmd => "-t $work -d ../../../.. html5lib_tree_construction/Makefile",
+                exp => "$obj/parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile",
+               skip => 0,
+         },
+        );
+
+    foreach (@args)
+    {
+        my %rec = %{ $_ };
+        next if ($rec{skip});
+
+        ## make-make while sitting in $objdir
+        mkdirr($rec{cwd});
+        chdir $rec{cwd} || die "chdir $rec{cwd} failed; $!";
+
+        makemakefile($rec{cmd});
+        my @errs;
+        if ($@)
+        {
+            push(@errs, "make-makefile $rec{cmd} failed: $@");
+        }
+        elsif (! -e $rec{exp})
+        {
+            push(@errs, "generated makefile does not exist: $rec{exp}");
+        }
+        ok(scalar(@errs), 0, "Errors detected: @errs");
+        find_ls($work) if (@errs);
+    }
+    chdir $FindBin::RealBin;
+} # check_makemakefile_legacy
+
+###########################################################################
+## Intent: Smoke tests for the unittests module
+###########################################################################
+sub smoke
+{
+    print STDERR "Running test: smoke()\n" if ($argv{debug});
+} # smoke()
+
+###########################################################################
+## Intent: Intitialize global test objects and consts
+###########################################################################
+sub init
+{
+    print "Running: init()\n" if ($argv{debug});
+#    testplan(24, 0);
+} # init()
+
+##----------------##
+##---]  MAIN  [---##
+##----------------##
+unless(GetOptions(\%argv,
+                  qw(
+                     debug|d
+                     manual
+                     test=s@
+                     verbose
+                     )))
+{
+    print "USAGE: $0\n";
+    print "  --debug    Enable script debug mode\n";
+    print "  --manual   Also run disabled tests\n";
+    print "  --smoke    Run smoke tests then exit\n";
+    print "  --test     Run a list of tests by function name\n";
+    print "  --verbose  Enable script verbose mode\n";
+    exit 1;
+}
+
+init();
+smoke();
+
+check_makemakefile();
+check_makemakefile_distinct();
+check_makemakefile_legacy();
new file mode 100644
--- /dev/null
+++ b/build/autoconf/test/makemakefile.tpm
@@ -0,0 +1,519 @@
+#!/usr/bin/env perl
+###########################################################################
+## Intent: Unit test to verify the makemakefile.pm module
+###########################################################################
+
+##----------------------------##
+##---] CORE/CPAN INCLUDES [---##
+##----------------------------##
+use strict;
+use warnings;
+#use feature 'state';
+use Getopt::Long;
+
+use FindBin;
+use Cwd         qw{abs_path};
+use File::Basename;
+use File::Compare;
+use File::Copy;
+use File::Temp  qw{tempdir};
+
+use Test;
+sub BEGIN { plan tests => 36 };
+my @workdirs;
+sub END { system("/bin/rm -fr @workdirs"); }  # cleanup behind interrupts
+
+##-------------------##
+##---]  EXPORTS  [---##
+##-------------------##
+our $VERSION = qw(1.0);
+
+##------------------##
+##---] INCLUDES [---##
+##------------------##
+use FindBin;
+use lib "$FindBin::RealBin/..";
+use makemakefile;
+
+##-------------------##
+##---]  GLOBALS  [---##
+##-------------------##
+my %argv;
+
+###########################################################################
+## Intent: Create a temp sandbox populated with sources
+## -----------------------------------------------------------------------
+## Args:
+##   array    files to copy into the temporary sandbox
+## Returns:
+##     $@     set on error
+##   array 
+##     top  - path to temp sandbox root
+##     obj  - path to temp sandbox moz_obj directory
+## -----------------------------------------------------------------------
+###########################################################################
+my $_root_; # state $root
+sub createSandbox
+{
+#    state $root;
+    my @errors;
+
+    unless ($_root_)
+    {
+        my @tmp = split(m%/%, $FindBin::RealBin);
+        splice(@tmp, -3);
+        $_root_ = join('/', @tmp);
+    }
+
+    my $work = tempdir(CLEANUP=>1);
+    push(@workdirs, $work);
+    my @dirs = map{ join('/', $work, dirname($_)) } @_;
+    mkdirr(@dirs);
+    push(@errors, "createSandbox: $@") if ($@);
+
+    foreach (@_)
+    {
+        ## Copy sources into the temp source directory
+        my $src = join('/', $_root_, $_);
+        my $dst = join('/', $work, $_);
+        unless (copy($src, $dst))
+        {
+            push(@errors, "copy($src, $dst) failed: $!");
+        }
+    }
+    print STDERR "createSandbox: $work\n" if ($main::argv{debug});
+    $@ = join('', map{ "$_\n" } @errors);
+    $work;
+} # createSandbox
+
+###########################################################################
+## Intent: Verify legacy dirname function
+###########################################################################
+sub check_dirname_legacy
+{
+    print "Running: check_dirname_legacy\n" if ($main::argv{debug});
+
+    foreach (
+        ['/dev/null', '/dev'],
+        ['/foo/bar/Makefile', '/foo/bar'],
+        )
+    {
+        my ($src, $exp) = @{ $_ };
+        my $dir = dirname_legacy($src);
+        ok($dir, $exp, "dirname_legacy($src) failed");
+    }
+
+    my $path = dirname_legacy(undef);
+    ok($path ? 1 : 0, 1, "dirname('') should expand to cwd");
+} # check_dirname_legacy
+
+###########################################################################
+## Intent: Verify topdir lookup function
+###########################################################################
+sub check_getTopDir
+{
+    print "Running: check_getTopDir\n" if ($main::argv{debug});
+
+    my $path = getTopDir();
+
+    ## Unit test is special, cmd not invoked from the same directory
+    ## as the makemakefile.pm module.
+    ok($path ? 1 : 0, 1, "getTopDir failed");
+    ok(-d $path ? 1 : 0, 1, "getTopDir: directory $path does not exist");
+    ok($FindBin::RealBin =~ m%$path/% ? 1 : 0, 1, 'Invalid topdir path');
+    ok(-e "$path/client.mk" ? 1 : 0, 1, "client.mk not found in $path");
+} # check_getTopDir
+
+###########################################################################
+## Intent: Verify objdir lookup function
+###########################################################################
+sub check_getObjDir
+{
+    print "Running: check_getObjDir\n" if ($main::argv{debug});
+    local $main::argv{obj} = '/bin';
+    my $path = getObjDir('_reset_');
+    ok($path ? 1 : 0, 1, "getObjDir failed");
+    ok(-d $path ? 1 : 0, 1, "getObjDir: directory $path does not exist");
+
+    my $top = getTopDir();
+    $main::argv{obj} = join('/', $top, 'browser'); # use existing path so file can be resolved
+    my $obj = getObjDir('_reset_');
+    ok($top ne $obj ? 1 : 0, 1, "top and object directory paths should not match");
+
+    ## If we fail for /bin use here getObjDir() was not reset
+    my $client = join('/', $obj, '..', 'client.mk');
+    ok(-e $client ? 1 : 0, 1, "client.mk not found in parent of $path, $client");
+    getObjDir('_set_'); # clear cached value and recompute
+
+    foreach my $file ("$top/memory/mozalloc/Makefile")
+    {
+        my $obj = getObjDir('_reset_', $file);
+        ok($obj ne $file ? 1 : 0, 1, "getObjDir($file) failed")
+    }
+} # check_getObjDir
+
+###########################################################################
+## Intent: Verify rel-path-to-root/getdepth function
+###########################################################################
+sub check_getDepth
+{
+    my @tmp = split(m%/%o, $FindBin::Bin);
+    splice(@tmp, -3);
+    my $root = abs_path( join('/', @tmp) );
+
+    my %data =
+        (
+         $root => '.',
+         join('/', $root, 'netwerk/Makefile.in') => '..',
+
+         join('/', $root, 'browser/components/privatebrowsing/test/browser/Makefile.in') => '../../../../..',
+         join('/', $root, 'browser/components/privatebrowsing/test/browser/') => '../../../../..',
+         join('/', $root, 'browser/components/privatebrowsing/test/browser') => '../../../../..',
+         join('/', $root, 'browser/components/privatebrowsing/test') => '../../../..',
+        );
+
+    while (my($k, $v) = each %data)
+    {
+        my $depth = makemakefile::getDepth($k);
+        ok($depth, $v, "getDepth($k) failed");
+    }
+} # check_getDepth
+
+###########################################################################
+## Intent: Verify reading the exclusion file
+###########################################################################
+sub check_getExclusions
+{
+    my $cfg = join('/', $FindBin::RealBin, 'make-makefile.excl');
+    my %excl = getExclusions($cfg);
+    ok($@, '', '$@ should not be set');
+
+    my @excl = sort keys %excl;
+    ok(scalar @excl, 4, "Exclusion file is invalid: \@excl=@excl");
+} # check_getExclusions
+
+###########################################################################
+## Intent: Verify rel-path-to-root function
+## -----------------------------------------------------------------------
+## Args:
+##   none
+## Returns:
+##   none
+## -----------------------------------------------------------------------
+## Note:
+##   String test only, top and obj paths are bogus for this test
+###########################################################################
+sub check_getRelPath
+{
+    my @tmp = split(m%/%o, $FindBin::Bin);
+    splice(@tmp, -3);
+    my $root = abs_path( join('/', @tmp) );
+    my $obj0 = 'obj-arch';
+    my $obj = join('/', $root, $obj0);
+
+    local $main::argv{top} = $root;
+    local $main::argv{obj} = $obj;
+    getTopDir('_reset_');
+    getObjDir('_set_', $obj);
+
+    ## Cannot test relative paths with objdir beneath /tmp
+    ## Commented paths are needed for full test coverage
+    ## but are not currently supported by all module functions.
+    my %data =
+        (
+         # Relative - path correct for build directory but 
+         'profile/dirserviceprovider/public/Makefile.in'                   => 'profile/dirserviceprovider/public',
+
+         join('/', $root, 'profile/dirserviceprovider/public/Makefile.in') => 'profile/dirserviceprovider/public',
+
+         # File search
+         'profile/dirserviceprovider/public'                               => 'profile/dirserviceprovider/public',
+
+         # cwd + cleanup
+         # '../../../profile/dirserviceprovider/public/Makefile.in'          => 'profile/dirserviceprovider/public',
+#         "../../../${obj0}/profile/dirserviceprovider/public/Makefile.in"  => 'profile/dirserviceprovider/public',
+
+         ## Special case: This could be handled but permutations of non-existent files, non-overlapping paths
+         ## and relative paths containing partial subdirectories will compilicate the logic.  Wait until needed.
+         ## Relative path: $root + obj + subdir
+#         "${obj0}/profile/dirserviceprovider/public/Makefile"          => 'profile/dirserviceprovider/public',
+         join('/', $obj, 'profile/dirserviceprovider/public/Makefile') => 'profile/dirserviceprovider/public',
+
+         # $RealBin, -d ../../..
+         # top and obj not subdirectories of each other:  /foo/x, /bar/y
+        );
+
+    while (my($k, $v) = each %data)
+    {
+        my $dir = getRelPath($k);
+        ok($@, '', '$@ should not be set');
+        ok($dir, $v, "ERROR[$k]: exp[$v] != found=[$dir]");
+    }
+
+
+    my $top = '/tmp/foo';
+    my $tmp = '/tmp/bar';
+    local $main::argv{top} = $tmp;
+    local $main::argv{obj} = $obj;
+
+    %data =
+        (
+#         "$top/profile/dirserviceprovider/public/Makefile.in" => 'profile/dirserviceprovider/public',
+         "$obj/profile/dirserviceprovider/public/Makefile"    => 'profile/dirserviceprovider/public',
+        );
+
+    while (my($k, $v) = each %data)
+    {
+        my $dir = getRelPath($k);
+        ok($dir, $v, "ERROR[$k]: exp[$v] != found=[$dir]");
+    }
+} # check_getRelPath
+
+###########################################################################
+## Intent: Verify rel-path-to-root directory creation
+###########################################################################
+sub check_mkdirr
+{
+    if (-w '/bin') # cygwin may be writable
+    {
+        ok(1, 1, 'bogus test to maintain count');
+    } else {
+        mkdirr('/bin/invalid/Makefile');
+        ok($@ ? 1 : 0, 1, '$@ should be set');
+    }
+
+    my $work = createSandbox();
+    my @paths = map{ join('/', $work, $_, 'Makefile.in') } qw (xyz/abc foo/bar a/b/c/d/e);
+    mkdirr(@paths);
+    ok($@ ? 1 : 0, 0, '$@ should not be set');
+
+    push(@paths, '/bin');
+
+    my @errors;
+    foreach (@paths)
+    {
+        my $dir = dirname($_);
+        next if (-d $dir);
+        push(@errors, "mkdirr($dir) failed\n");
+    }
+    ok(scalar @errors, 0, "Errors detected: @errors");
+} # check_mkdirr
+
+###########################################################################
+## Intent: Verify permutations for system("config.status")
+###########################################################################
+sub check_run_config_status
+{
+    print STDERR "Running: check_run_config_status()\n"
+        if ($main::argv{debug});
+
+    my $work = createSandbox();
+    chdir $work;
+    run_config_status();
+    ok($@ ? 1 : 0, '$@ should be set, config.status does not exist');
+
+    my $cfg = join('/', $work, 'config.status');
+    local *CFG;
+    open(CFG, "> $cfg") && close(CFG);
+    run_config_status();
+    ok($@, qr/config.status failed/, '$@ should be set, config.status is not executabl');
+
+    open(CFG, "> $cfg");
+    print CFG join("\n",
+		   '#!/bin/sh',
+		   '',
+		   'true',
+		   '');
+    close(CFG);
+    chmod 0555, $cfg;
+    run_config_status();
+    ok($@, qr/config.status failed/, '$@ should not be set');
+		   
+} # check_run_config_status
+
+###########################################################################
+## Intent: Verify makefile generation by legacy make-makefile functions
+##   o make-makefile -t /x/y -d ..
+###########################################################################
+sub check_update_makefiles_legacy
+{
+    print STDERR "Running: check_update_makefiles_legacy()\n"
+        if ($main::argv{debug});
+    
+    return unless ($argv{legacy});
+    print STDERR "check_update_makefiles_legacy: not yet implemented\n";
+
+} # check_update_makefiles_legacy
+
+###########################################################################
+## Intent: Verify updateMakefiles()
+##   o a makefile is generated when none exists.
+##   o a makefile will only be updated when the templates changes.
+##   o existing makefiles will be updated when the template changes.
+##   o @foo@ tokens have been expanded
+###########################################################################
+sub check_updateMakefiles
+{
+    my @errors;
+
+    print STDERR "Running: check_updateMakefiles()\n"
+        if ($main::argv{debug});
+
+    my $mf = 'memory/mozalloc/Makefile.in';
+
+    my $work = createSandbox($mf);
+    my $obj = join('/', $work, 'obj');
+    my %args =
+        (
+         top => $work,
+         obj => $obj,
+        );
+
+    my $mf_src = join('/', $work, 'memory/mozalloc/Makefile.in');
+    my $mf_dst = join('/', $obj, 'memory/mozalloc/Makefile');
+
+    updateMakefiles('memory/mozalloc', \%args);