diff -ruN oolite.orig/Makefile oolite/Makefile
--- oolite.orig/Makefile	2014-09-11 00:50:31.000000000 +0400
+++ oolite/Makefile	2014-10-20 00:26:39.000000000 +0400
@@ -2,52 +2,98 @@
 # $FreeBSD: head/games/oolite/Makefile 367888 2014-09-10 20:50:31Z gerald $
 
 PORTNAME=		oolite
-PORTVERSION=		1.76
-PORTREVISION=	4
+PORTVERSION=		1.80
 CATEGORIES=		games gnustep
-MASTER_SITES=		${MASTER_SITE_BERLIOS} http://jens.ayton.se/oolite/deps/:js
-MASTER_SITE_SUBDIR=	oolite-linux
-DISTFILES=		${PORTNAME}-source-${PORTVERSION}${EXTRACT_SUFX} \
-			firefox-4.0.source.js-only.tbz:js
+MASTER_SITES=		http://github.com/OoliteProject/oolite/releases/download/1.80b/
+DISTNAME=		${PORTNAME}-source-${PORTVERSION}
 DIST_SUBDIR=		oolite
-EXTRACT_ONLY=		${PORTNAME}-source-${PORTVERSION}${EXTRACT_SUFX}
 
 MAINTAINER=		avg@icyb.net.ua
 COMMENT=		Trade and combat space simulator, clone of Elite
 
+LICENSE=	CCBYNCSAv3 GPLv2 ZLIB
+LICENSE_COMB=	multi
+LICENSE_NAME_CCBYNCSAv3=	Creative Commons Attribution-NonCommercial-ShareAlike License version 3.0
+LICENSE_FILE_CCBYNCSAv3=	${WRKSRC}/Doc/LICENSE.TXT
+LICENSE_PERMS_CCBYNCSAv3=	dist-mirror pkg-mirror auto-accept
+
 BUILD_DEPENDS=		zip:${PORTSDIR}/archivers/zip \
 			${LOCALBASE}/bin/unzip:${PORTSDIR}/archivers/unzip
 LIB_DEPENDS=		libespeak.so:${PORTSDIR}/audio/espeak \
-			libnspr4.so:${PORTSDIR}/devel/nspr
+			libnspr4.so:${PORTSDIR}/devel/nspr \
+			libvorbisfile.so:${PORTSDIR}/audio/libvorbis \
+			libpng15.so:${PORTSDIR}/graphics/png \
+			libminizip.so:${PORTSDIR}/archivers/minizip
 
-USES=			gmake perl5 tar:bzip2
+USES=			gmake perl5 tar:bzip2 python:build openal:al
 USE_GL=			yes
-USE_SDL=		mixer image gfx
+USE_SDL=		sdl
 USE_GNUSTEP=		yes
 USE_GNUSTEP_BASE=	yes
 USE_GNUSTEP_BUILD=	yes
 USE_MAKEFILE=		yes
 ALL_TARGET=		release-deployment
 USE_PERL5=		build
-USE_PYTHON_BUILD=	yes
-
-SUB_FILES=		pkg-message
-PKGMESSAGE=		${WRKDIR}/pkg-message
-
-WRKSRC=			${WRKDIR}/${PORTNAME}-source-${PORTVERSION}
 
-post-extract:
-	@(cd ${WRKSRC}/deps/Cross-platform-deps && \
-		${BZIP2_CMD} -dc ${_DISTDIR}/firefox-4.0.source.js-only.tbz | ${TAR} -xf - && \
-		${MV} mozilla-2.0 mozilla && \
-		${ECHO_CMD} 'http://jens.ayton.se/oolite/deps/firefox-4.0.source.js-only.tbz' > mozilla/current.url \
-	)
+SUB_FILES=	oolite
+SUB_LIST=	GNUSTEP_SYSTEM_TOOLS="${GNUSTEP_SYSTEM_TOOLS}"
 
+WRKSRC=	${WRKDIR}/${DISTNAME}
+RELEASEDIR=	${WRKSRC}/oolite.app
+DATADIR=	${GNUSTEP_LOCAL_APPS}/oolite.app
+PORTDATA=	Resources
+PORTDOCS=	*.pdf CHANGELOG.TXT contributors.txt
+
+PLIST_FILES+=	bin/oolite %%DATADIR%%/oolite \
+		share/applications/oolite.desktop \
+		share/pixmaps/oolite-icon.png
+
+OPTIONS_DEFINE=	DOCS
+
+DO_COMPILER_CHANGE=	0
+
+.if exists(/usr/bin/clang)
+CCVERSION!=	/usr/bin/clang --version
+COMPILER_VERSION=	${CCVERSION:M[0-9].[0-9]*:C/([0-9]).?/\1/g}
+COMPILER_IS_CLANG=	${CCVERSION:Mclang}
+
+# Check for LLVM/Clang v3.4.1, which is broken for Oolite v1.80
+.if ${COMPILER_IS_CLANG} && ${COMPILER_VERSION} == 341
+DO_COMPILER_CHANGE=	1
+.endif
+.endif
+
+.include <bsd.port.pre.mk>
+
+.if ${OSVERSION} < 900014 || ${DO_COMPILER_CHANGE}
+BUILD_DEPENDS+=	clang33:${PORTSDIR}/lang/clang33
+CC=		${LOCALBASE}/bin/clang33
+CXX=	${LOCALBASE}/bin/clang++33
+CPP=	${LOCALBASE}/bin/clang-cpp33
+.endif
+
+post-patch: .SILENT
+	${REINPLACE_CMD} -e 's/GNUSTEP_USER_ROOT/GNUSTEP_LOCAL_ROOT/ ; \
+		s/sdl-config/$${SDL_CONFIG}/ ; \
+		s|-lstdc++|`$${SDL_CONFIG} --libs` -lstdc++| ; \
+		s|:src/Core/MiniZip|| ; \
+		s|-Isrc/Core/MiniZip|-I$${LOCALBASE}/include/minizip| ; \
+		s|-lz|-lminizip| ; \
+		/ioapi.c/d ; /unzip.c/d ; \
+		s|/usr/X11R6|$${LOCALBASE}|' \
+		${WRKSRC}/GNUmakefile
+# Conversion needed for unsigned int type for using isfinite function
+	${REINPLACE_CMD} -e 's|isfinite(uValue)|isfinite((long double)uValue)|' \
+		${WRKSRC}/src/Core/Scripting/OOJSPlayerShip.m
+# Change value of the SAVEDIR define
+	${REINPLACE_CMD} -e 's|oolite-saves|\.oolite-saves|' \
+		${WRKSRC}/src/Core/NSFileManagerOOExtensions.h
 do-install:
-	${MKDIR} ${STAGEDIR}${PREFIX}/GNUstep/Local/Applications
-	${CP} -R ${WRKSRC}/oolite.app ${STAGEDIR}${PREFIX}/GNUstep/Local/Applications
-	${STRIP_CMD} ${STAGEDIR}${PREFIX}/GNUstep/Local/Applications/oolite.app/oolite
+	cd ${RELEASEDIR} && ${COPYTREE_SHARE} "${PORTDATA}" ${STAGEDIR}${DATADIR}
+	${INSTALL_SCRIPT} ${WRKDIR}/oolite ${STAGEDIR}${PREFIX}/bin
+	${INSTALL_PROGRAM} ${RELEASEDIR}/oolite ${STAGEDIR}${DATADIR}
 	${INSTALL_DATA} ${WRKSRC}/installers/FreeDesktop/oolite.desktop ${STAGEDIR}${PREFIX}/share/applications
 	${INSTALL_DATA} ${WRKSRC}/installers/FreeDesktop/oolite-icon.png ${STAGEDIR}${PREFIX}/share/pixmaps
+	cd ${WRKSRC}/Doc && ${COPYTREE_SHARE} "${PORTDOCS}" ${STAGEDIR}${DOCSDIR}
 
-.include <bsd.port.mk>
+.include <bsd.port.post.mk>
diff -ruN oolite.orig/distinfo oolite/distinfo
--- oolite.orig/distinfo	2014-01-22 19:30:13.000000000 +0400
+++ oolite/distinfo	2014-09-23 06:51:48.000000000 +0400
@@ -1,4 +1,2 @@
-SHA256 (oolite/oolite-source-1.76.tar.bz2) = cc5054432b4e1ad316ed5f52c88036cb8fc9732d42969225993f79ae3e93ff11
-SIZE (oolite/oolite-source-1.76.tar.bz2) = 44739650
-SHA256 (oolite/firefox-4.0.source.js-only.tbz) = 173b8798043612e50fa7618858c3a92d06f1f439d6d336a5700548cc5d75580a
-SIZE (oolite/firefox-4.0.source.js-only.tbz) = 6198554
+SHA256 (oolite/oolite-source-1.80.tar.bz2) = a9bea03435cd7fd05b4519a44345e4ff4857a799aef79913733ddc5d7a537bdf
+SIZE (oolite/oolite-source-1.80.tar.bz2) = 139397592
diff -ruN oolite.orig/files/oolite.in oolite/files/oolite.in
--- oolite.orig/files/oolite.in	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/oolite.in	2014-09-24 10:49:38.000000000 +0400
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+%%GNUSTEP_SYSTEM_TOOLS%%/openapp oolite "$@"
diff -ruN oolite.orig/files/patch-GNUmakefile oolite/files/patch-GNUmakefile
--- oolite.orig/files/patch-GNUmakefile	2014-01-22 21:40:44.000000000 +0400
+++ oolite/files/patch-GNUmakefile	1970-01-01 03:00:00.000000000 +0300
@@ -1,24 +0,0 @@
---- GNUmakefile.orig	2011-12-15 12:54:49.000000000 +0200
-+++ GNUmakefile	2012-02-23 19:59:43.906322555 +0200
-@@ -4,7 +4,7 @@ include config.make
- vpath %.m src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug
- vpath %.h src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug
- vpath %.c src/SDL:src/Core:src/BSDCompat:src/Core/Debug
--GNUSTEP_INSTALLATION_DIR         = $(GNUSTEP_USER_ROOT)
-+GNUSTEP_INSTALLATION_DIR         = $(GNUSTEP_LOCAL_ROOT)
- GNUSTEP_OBJ_DIR_BASENAME         := $(GNUSTEP_OBJ_DIR_NAME)
- HOST_ARCH                        := $(shell echo $(GNUSTEP_HOST_CPU) | sed -e s/i.86/x86/ -e s/amd64/x86_64/ )
- ifeq ($(GNUSTEP_HOST_OS),mingw32)
-@@ -37,10 +37,10 @@ else
-     LIBJS = js_static
- 
-     ADDITIONAL_INCLUDE_DIRS      = -I$(LIBJS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables
--    ADDITIONAL_OBJC_LIBS         = -lGLU -lGL -lX11 -lSDL -lSDL_mixer -lgnustep-base -l$(LIBJS) `nspr-config --libs` -lstdc++
-+    ADDITIONAL_OBJC_LIBS         = -lGLU -lGL -lX11 -lSDL -lSDL_mixer -lgnustep-base -l$(LIBJS) `nspr-config --libs` `sdl-config --libs` -lstdc++
-     ADDITIONAL_CFLAGS            = -Wall -DLINUX -DNEED_STRLCPY `sdl-config --cflags` `nspr-config --cflags`
-     ADDITIONAL_OBJCFLAGS         = -Wall -std=c99 -DLOADSAVEGUI -DLINUX -DXP_UNIX -Wno-import `sdl-config --cflags` `nspr-config --cflags`
--    oolite_LIB_DIRS              += -L/usr/X11R6/lib/ -L$(LIBJS_LIB_DIR)
-+    oolite_LIB_DIRS              += -L${LOCALBASE}/lib/ -L$(LIBJS_LIB_DIR)
- 
-     ifeq ($(use_deps),yes)
-         oolite_LIB_DIRS          += -Ldeps/Linux-deps/$(HOST_ARCH)/lib_linker
diff -ruN oolite.orig/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers oolite/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers
--- oolite.orig/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers	2014-01-22 21:40:44.000000000 +0400
+++ oolite/files/patch-deps_Cross-platform-deps_mozilla_js_src_config_system-headers	1970-01-01 03:00:00.000000000 +0300
@@ -1,10 +0,0 @@
---- deps/Cross-platform-deps/mozilla/js/src/config/system-headers.orig	2012-03-04 13:03:24.492124042 +0200
-+++ deps/Cross-platform-deps/mozilla/js/src/config/system-headers	2012-03-04 13:03:42.634121018 +0200
-@@ -609,6 +609,7 @@ proto/exec.h
- psap.h
- Pt.h
- pthread.h
-+pthread_np.h
- pwd.h
- Python.h
- QDOffscreen.h
diff -ruN oolite.orig/files/patch-deps_mozilla-bug771281 oolite/files/patch-deps_mozilla-bug771281
--- oolite.orig/files/patch-deps_mozilla-bug771281	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-deps_mozilla-bug771281	2014-09-23 08:05:08.000000000 +0400
@@ -0,0 +1,1840 @@
+diff -ruN deps.orig/mozilla/js/src/shell/Makefile.in deps/mozilla/js/src/shell/Makefile.in
+--- deps.orig/mozilla/js/src/shell/Makefile.in	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/shell/Makefile.in	2014-09-23 07:59:03.000000000 +0400
+@@ -47,7 +47,6 @@
+ PROGRAM         = js$(BIN_SUFFIX)
+ CPPSRCS		= \
+   js.cpp \
+-  jsworkers.cpp \
+   $(NULL)
+ 
+ DEFINES         += -DEXPORT_JS_API
+diff -ruN deps.orig/mozilla/js/src/shell/js.cpp deps/mozilla/js/src/shell/js.cpp
+--- deps.orig/mozilla/js/src/shell/js.cpp	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/shell/js.cpp	2014-09-23 07:59:03.000000000 +0400
+@@ -91,8 +91,6 @@
+ #endif /* JSDEBUGGER_C_UI */
+ #endif /* JSDEBUGGER */
+ 
+-#include "jsworkers.h"
+-
+ #include "jsinterpinlines.h"
+ #include "jsobjinlines.h"
+ #include "jsscriptinlines.h"
+@@ -194,10 +192,6 @@
+ JSBool gQuitting = JS_FALSE;
+ FILE *gErrFile = NULL;
+ FILE *gOutFile = NULL;
+-#ifdef JS_THREADSAFE
+-JSObject *gWorkers = NULL;
+-js::workers::ThreadPool *gWorkerThreadPool = NULL;
+-#endif
+ 
+ static JSBool reportWarnings = JS_TRUE;
+ static JSBool compileOnly = JS_FALSE;
+@@ -1324,10 +1318,6 @@
+     JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &gExitCode);
+ 
+     gQuitting = JS_TRUE;
+-#ifdef JS_THREADSAFE
+-    if (gWorkerThreadPool)
+-        js::workers::terminateAll(JS_GetRuntime(cx), gWorkerThreadPool);
+-#endif
+     return JS_FALSE;
+ }
+ 
+@@ -4164,10 +4154,6 @@
+     gCanceled = true;
+     if (gExitCode == 0)
+         gExitCode = EXITCODE_TIMEOUT;
+-#ifdef JS_THREADSAFE
+-    if (gWorkerThreadPool)
+-        js::workers::terminateAll(rt, gWorkerThreadPool);
+-#endif
+     JS_TriggerAllOperationCallbacks(rt);
+ 
+     static const char msg[] = "Script runs for too long, terminating.\n";
+@@ -5695,29 +5681,8 @@
+ #endif /* JSDEBUGGER_C_UI */
+ #endif /* JSDEBUGGER */
+ 
+-#ifdef JS_THREADSAFE
+-    class ShellWorkerHooks : public js::workers::WorkerHooks {
+-    public:
+-        JSObject *newGlobalObject(JSContext *cx) {
+-            return NewGlobalObject(cx, NEW_COMPARTMENT);
+-        }
+-    };
+-    ShellWorkerHooks hooks;
+-    if (!JS_AddNamedObjectRoot(cx, &gWorkers, "Workers") ||
+-        (gWorkerThreadPool = js::workers::init(cx, &hooks, glob, &gWorkers)) == NULL) {
+-        return 1;
+-    }
+-#endif
+-
+     int result = ProcessArgs(cx, glob, argv, argc);
+ 
+-#ifdef JS_THREADSAFE
+-    js::workers::finish(cx, gWorkerThreadPool);
+-    JS_RemoveObjectRoot(cx, &gWorkers);
+-    if (result == 0)
+-        result = gExitCode;
+-#endif
+-
+ #ifdef JSDEBUGGER
+     if (jsdc) {
+ #ifdef JSDEBUGGER_C_UI
+diff -ruN deps.orig/mozilla/js/src/shell/jsworkers.cpp.rej deps/mozilla/js/src/shell/jsworkers.cpp.rej
+--- deps.orig/mozilla/js/src/shell/jsworkers.cpp.rej	1970-01-01 03:00:00.000000000 +0300
++++ deps/mozilla/js/src/shell/jsworkers.cpp.rej	2014-09-23 07:59:03.000000000 +0400
+@@ -0,0 +1,1281 @@
++@@ -1,1280 +0,0 @@
++-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++- * vim: set ts=8 sw=4 et tw=99:
++- *
++- * ***** 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 JavaScript shell workers.
++- *
++- * The Initial Developer of the Original Code is
++- * Mozilla Corporation.
++- * Portions created by the Initial Developer are Copyright (C) 2010
++- * the Initial Developer. All Rights Reserved.
++- *
++- * Contributor(s):
++- *   Jason Orendorff <jorendorff@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 ***** */
++-
++-#ifdef JS_THREADSAFE
++-
++-#include <algorithm>
++-#include <string.h>
++-#include "prthread.h"
++-#include "prlock.h"
++-#include "prcvar.h"
++-#include "jsapi.h"
++-#include "jscntxt.h"
++-#include "jshashtable.h"
++-#include "jsstdint.h"
++-#include "jslock.h"
++-#include "jsvector.h"
++-#include "jsworkers.h"
++-
++-extern size_t gMaxStackSize;
++-
++-/*
++- * JavaScript shell workers.
++- *
++- * == Object lifetime rules ==
++- *
++- *   - The ThreadPool lasts from init() to finish().
++- *
++- *   - The ThreadPool owns the MainQueue and the WorkerQueue. Those live from
++- *     the time the first Worker is created until finish().
++- *
++- *   - Each JS Worker object has the same lifetime as the corresponding C++
++- *     Worker object. A Worker is live if (a) the Worker JSObject is still
++- *     live; (b) the Worker has an incoming event pending or running; (c) it
++- *     has sent an outgoing event to its parent that is still pending; or (d)
++- *     it has any live child Workers.
++- *
++- *   - finish() continues to wait for events until all threads are idle.
++- *
++- * Event objects, however, are basically C++-only. The JS Event objects are
++- * just plain old JSObjects. They don't keep anything alive.
++- *
++- * == Locking scheme ==
++- *
++- * When mixing mutexes and the JSAPI request model, there are two choices:
++- *
++- *   - Always nest the mutexes in requests. Since threads in requests are not
++- *     supposed to block, this means the mutexes must be only briefly held.
++- *
++- *   - Never nest the mutexes in requests. Since this allows threads to race
++- *     with the GC, trace() methods must go through the mutexes just like
++- *     everyone else.
++- *
++- * This code uses the latter approach for all locks.
++- *
++- * In one case, a thread holding a Worker's mutex can acquire the mutex of one
++- * of its child Workers. See Worker::terminateSelf. (This can't deadlock because
++- * the parent-child relationship is a partial order.)
++- */
++-
++-namespace js {
++-namespace workers {
++-
++-template <class T, class AllocPolicy>
++-class Queue {
++-  private:
++-    typedef Vector<T, 4, AllocPolicy> Vec;
++-    Vec v1;
++-    Vec v2;
++-    Vec *front;
++-    Vec *back;
++-
++-    // Queue is not copyable.
++-    Queue(const Queue &);
++-    Queue & operator=(const Queue &);
++-
++-  public:
++-    Queue() : front(&v1), back(&v2) {}
++-    bool push(T t) { return back->append(t); }
++-    bool empty() { return front->empty() && back->empty(); }
++-
++-    T pop() {
++-        if (front->empty()) {
++-            std::reverse(back->begin(), back->end());
++-            Vec *tmp = front;
++-            front = back;
++-            back = tmp;
++-        }
++-        T item = front->back();
++-        front->popBack();
++-        return item;
++-    }        
++-
++-    void clear() {
++-        v1.clear();
++-        v2.clear();
++-    }
++-
++-    void trace(JSTracer *trc) {
++-        for (T *p = v1.begin(); p != v1.end(); p++)
++-            (*p)->trace(trc);
++-        for (T *p = v2.begin(); p != v2.end(); p++)
++-            (*p)->trace(trc);
++-    }
++-};
++-
++-class Event;
++-class ThreadPool;
++-class Worker;
++-
++-class WorkerParent {
++-  protected:
++-    typedef HashSet<Worker *, DefaultHasher<Worker *>, SystemAllocPolicy> ChildSet;
++-    ChildSet children;
++-
++-    bool initWorkerParent() { return children.init(8); }
++-
++-  public:
++-    virtual JSLock *getLock() = 0;
++-    virtual ThreadPool *getThreadPool() = 0;
++-    virtual bool post(Event *item) = 0;  // false on OOM or queue closed
++-    virtual void trace(JSTracer *trc) = 0;
++-
++-    bool addChild(Worker *w) {
++-        AutoLock hold(getLock());
++-        return children.put(w) != NULL;
++-    }
++-
++-    // This must be called only from GC or when all threads are shut down. It
++-    // does not bother with locking.
++-    void removeChild(Worker *w) {
++-        ChildSet::Ptr p = children.lookup(w);
++-        JS_ASSERT(p);
++-        children.remove(p);
++-    }
++-
++-    void disposeChildren();
++-};
++-
++-template <class T>
++-class ThreadSafeQueue
++-{
++-  protected:
++-    Queue<T, SystemAllocPolicy> queue;
++-    JSLock *lock;
++-    PRCondVar *condvar;
++-    bool closed;
++-
++-  private:
++-    Vector<T, 8, SystemAllocPolicy> busy;
++-
++-  protected:
++-    ThreadSafeQueue() : lock(NULL), condvar(NULL), closed(false) {}
++-
++-    ~ThreadSafeQueue() {
++-        if (condvar)
++-            JS_DESTROY_CONDVAR(condvar);
++-        if (lock)
++-            JS_DESTROY_LOCK(lock);
++-    }
++-
++-    // Called by take() with the lock held.
++-    virtual bool shouldStop() { return closed; }
++-
++-  public:
++-    bool initThreadSafeQueue() {
++-        JS_ASSERT(!lock);
++-        JS_ASSERT(!condvar);
++-        return (lock = JS_NEW_LOCK()) && (condvar = JS_NEW_CONDVAR(lock));
++-    }
++-
++-    bool post(T t) {
++-        AutoLock hold(lock);
++-        if (closed)
++-            return false;
++-        if (queue.empty())
++-            JS_NOTIFY_ALL_CONDVAR(condvar);
++-        return queue.push(t);
++-    }
++-
++-    void close() {
++-        AutoLock hold(lock);
++-        closed = true;
++-        queue.clear();
++-        JS_NOTIFY_ALL_CONDVAR(condvar);
++-    }
++-
++-    // The caller must hold the lock.
++-    bool take(T *t) {
++-        while (queue.empty()) {
++-            if (shouldStop())
++-                return false;
++-            JS_WAIT_CONDVAR(condvar, JS_NO_TIMEOUT);
++-        }
++-        *t = queue.pop();
++-        busy.append(*t);
++-        return true;
++-    }
++-
++-    // The caller must hold the lock.
++-    void drop(T item) {
++-        for (T *p = busy.begin(); p != busy.end(); p++) {
++-            if (*p == item) {
++-                *p = busy.back();
++-                busy.popBack();
++-                return;
++-            }
++-        }
++-        JS_NOT_REACHED("removeBusy");
++-    }
++-
++-    bool lockedIsIdle() { return busy.empty() && queue.empty(); }
++-
++-    bool isIdle() {
++-        AutoLock hold(lock);
++-        return lockedIsIdle();
++-    }
++-
++-    void wake() {
++-        AutoLock hold(lock);
++-        JS_NOTIFY_ALL_CONDVAR(condvar);
++-    }
++-
++-    void trace(JSTracer *trc) {
++-        AutoLock hold(lock);
++-        for (T *p = busy.begin(); p != busy.end(); p++)
++-            (*p)->trace(trc);
++-        queue.trace(trc);
++-    }
++-};
++-
++-class MainQueue;
++-
++-class Event
++-{
++-  protected:
++-    virtual ~Event() { JS_ASSERT(!data); }
++-
++-    WorkerParent *recipient;
++-    Worker *child;
++-    uint64 *data;
++-    size_t nbytes;
++-
++-  public:
++-    enum Result { fail = JS_FALSE, ok = JS_TRUE, forwardToParent };
++-
++-    virtual void destroy(JSContext *cx) { 
++-        JS_free(cx, data);
++-#ifdef DEBUG
++-        data = NULL;
++-#endif
++-        delete this;
++-    }
++-
++-    void setChildAndRecipient(Worker *aChild, WorkerParent *aRecipient) {
++-        child = aChild;
++-        recipient = aRecipient;
++-    }
++-
++-    bool deserializeData(JSContext *cx, jsval *vp) {
++-        return !!JS_ReadStructuredClone(cx, data, nbytes, JS_STRUCTURED_CLONE_VERSION, vp,
++-                                        NULL, NULL);
++-    }
++-
++-    virtual Result process(JSContext *cx) = 0;
++-
++-    inline void trace(JSTracer *trc);
++-
++-    template <class EventType>
++-    static EventType *createEvent(JSContext *cx, WorkerParent *recipient, Worker *child,
++-                                  jsval v)
++-    {
++-        uint64 *data;
++-        size_t nbytes;
++-        if (!JS_WriteStructuredClone(cx, v, &data, &nbytes, NULL, NULL))
++-            return NULL;
++-
++-        EventType *event = new EventType;
++-        if (!event) {
++-            JS_ReportOutOfMemory(cx);
++-            return NULL;
++-        }
++-        event->recipient = recipient;
++-        event->child = child;
++-        event->data = data;
++-        event->nbytes = nbytes;
++-        return event;
++-    }
++-
++-    Result dispatch(JSContext *cx, JSObject *thisobj, const char *dataPropName,
++-                    const char *methodName, Result noHandler)
++-    {
++-        if (!data)
++-            return fail;
++-
++-        JSBool found;
++-        if (!JS_HasProperty(cx, thisobj, methodName, &found))
++-            return fail;
++-        if (!found)
++-            return noHandler;
++-
++-        // Create event object.
++-        jsval v;
++-        if (!deserializeData(cx, &v))
++-            return fail;
++-        JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
++-        if (!obj || !JS_DefineProperty(cx, obj, dataPropName, v, NULL, NULL, 0))
++-            return fail;
++-
++-        // Call event handler.
++-        jsval argv[1] = { OBJECT_TO_JSVAL(obj) };
++-        jsval rval = JSVAL_VOID;
++-        return Result(JS_CallFunctionName(cx, thisobj, methodName, 1, argv, &rval));
++-    }
++-};
++-
++-typedef ThreadSafeQueue<Event *> EventQueue;
++-
++-class MainQueue : public EventQueue, public WorkerParent
++-{
++-  private:
++-    ThreadPool *threadPool;
++-
++-  public:
++-    explicit MainQueue(ThreadPool *tp) : threadPool(tp) {}
++-
++-    ~MainQueue() {
++-        JS_ASSERT(queue.empty());
++-    }
++-
++-    bool init() { return initThreadSafeQueue() && initWorkerParent(); }
++-
++-    void destroy(JSContext *cx) {
++-        while (!queue.empty())
++-            queue.pop()->destroy(cx);
++-        delete this;
++-    }
++-
++-    virtual JSLock *getLock() { return lock; }
++-    virtual ThreadPool *getThreadPool() { return threadPool; }
++-
++-  protected:
++-    virtual bool shouldStop();
++-
++-  public:
++-    virtual bool post(Event *event) { return EventQueue::post(event); }
++-
++-    virtual void trace(JSTracer *trc);
++-
++-    void traceChildren(JSTracer *trc) { EventQueue::trace(trc); }
++-
++-    JSBool mainThreadWork(JSContext *cx, bool continueOnError) {
++-        JSAutoSuspendRequest suspend(cx);
++-        AutoLock hold(lock);
++-
++-        Event *event;
++-        while (take(&event)) {
++-            JS_RELEASE_LOCK(lock);
++-            Event::Result result;
++-            {
++-                JSAutoRequest req(cx);
++-                result = event->process(cx);
++-                if (result == Event::forwardToParent) {
++-                    // FIXME - pointlessly truncates the string to 8 bits
++-                    jsval data;
++-                    JSAutoByteString bytes;
++-                    if (event->deserializeData(cx, &data) &&
++-                        JSVAL_IS_STRING(data) &&
++-                        bytes.encode(cx, JSVAL_TO_STRING(data))) {
++-                        JS_ReportError(cx, "%s", bytes.ptr());
++-                    } else {
++-                        JS_ReportOutOfMemory(cx);
++-                    }
++-                    result = Event::fail;
++-                }
++-                if (result == Event::fail && continueOnError) {
++-                    if (JS_IsExceptionPending(cx) && !JS_ReportPendingException(cx))
++-                        JS_ClearPendingException(cx);
++-                    result = Event::ok;
++-                }
++-            }
++-            JS_ACQUIRE_LOCK(lock);
++-            drop(event);
++-            event->destroy(cx);
++-            if (result != Event::ok)
++-                return false;
++-        }
++-        return true;
++-    }
++-};
++-
++-/*
++- * A queue of workers.
++- *
++- * We keep a queue of workers with pending events, rather than a queue of
++- * events, so that two threads won't try to run a Worker at the same time.
++- */
++-class WorkerQueue : public ThreadSafeQueue<Worker *>
++-{
++-  private:
++-    MainQueue *main;
++-
++-  public:
++-    explicit WorkerQueue(MainQueue *main) : main(main) {}
++-
++-    void work();
++-};
++-
++-/* The top-level object that owns everything else. */
++-class ThreadPool
++-{
++-  private:
++-    enum { threadCount = 6 };
++-
++-    JSObject *obj;
++-    WorkerHooks *hooks;
++-    MainQueue *mq;
++-    WorkerQueue *wq;
++-    PRThread *threads[threadCount];
++-    int32_t terminating;
++-
++-    static JSClass jsClass;
++-
++-    static void start(void* arg) {
++-        ((WorkerQueue *) arg)->work();
++-    }
++-
++-    explicit ThreadPool(WorkerHooks *hooks) : hooks(hooks), mq(NULL), wq(NULL), terminating(0) {
++-        for (int i = 0; i < threadCount; i++)
++-            threads[i] = NULL;
++-    }
++-
++-  public:
++-    ~ThreadPool() {
++-        JS_ASSERT(!mq);
++-        JS_ASSERT(!wq);
++-        JS_ASSERT(!threads[0]);
++-    }
++-
++-    static ThreadPool *create(JSContext *cx, WorkerHooks *hooks) {
++-        ThreadPool *tp = new ThreadPool(hooks);
++-        if (!tp) {
++-            JS_ReportOutOfMemory(cx);
++-            return NULL;
++-        }
++-
++-        JSObject *obj = JS_NewObject(cx, &jsClass, NULL, NULL);
++-        if (!obj || !JS_SetPrivate(cx, obj, tp)) {
++-            delete tp;
++-            return NULL;
++-        }
++-        tp->obj = obj;
++-        return tp;
++-    }
++-
++-    JSObject *asObject() { return obj; }
++-    WorkerHooks *getHooks() { return hooks; }
++-    WorkerQueue *getWorkerQueue() { return wq; }
++-    MainQueue *getMainQueue() { return mq; }
++-    bool isTerminating() { return terminating != 0; }
++-
++-    /*
++-     * Main thread only. Requires request (to prevent GC, which could see the
++-     * object in an inconsistent state).
++-     */
++-    bool start(JSContext *cx) {
++-        JS_ASSERT(!mq && !wq);
++-        mq = new MainQueue(this);
++-        if (!mq || !mq->init()) {
++-            mq->destroy(cx);
++-            mq = NULL;
++-            return false;
++-        }
++-        wq = new WorkerQueue(mq);
++-        if (!wq || !wq->initThreadSafeQueue()) {
++-            delete wq;
++-            wq = NULL;
++-            mq->destroy(cx);
++-            mq = NULL;
++-            return false;
++-        }
++-        JSAutoSuspendRequest suspend(cx);
++-        bool ok = true;
++-        for (int i = 0; i < threadCount; i++) {
++-            threads[i] = PR_CreateThread(PR_USER_THREAD, start, wq, PR_PRIORITY_NORMAL,
++-                                         PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
++-            if (!threads[i]) {
++-                shutdown(cx);
++-                ok = false;
++-                break;
++-            }
++-        }
++-        return ok;
++-    }
++-
++-    void terminateAll(JSRuntime *rt) {
++-        // See comment about JS_ATOMIC_SET in the implementation of
++-        // JS_TriggerOperationCallback.
++-        JS_ATOMIC_SET(&terminating, 1);
++-        JS_TriggerAllOperationCallbacks(rt);
++-    }
++-
++-    /* This context is used only to free memory. */
++-    void shutdown(JSContext *cx) {
++-        wq->close();
++-        for (int i = 0; i < threadCount; i++) {
++-            if (threads[i]) {
++-                PR_JoinThread(threads[i]);
++-                threads[i] = NULL;
++-            }
++-        }
++-
++-        delete wq;
++-        wq = NULL;
++-
++-        mq->disposeChildren();
++-        mq->destroy(cx);
++-        mq = NULL;
++-        terminating = 0;
++-    }
++-
++-  private:
++-    static void jsTraceThreadPool(JSTracer *trc, JSObject *obj) {
++-        ThreadPool *tp = unwrap(trc->context, obj);
++-        if (tp->mq) {
++-            tp->mq->traceChildren(trc);
++-            tp->wq->trace(trc);
++-        }
++-    }
++-
++-
++-    static void jsFinalize(JSContext *cx, JSObject *obj) {
++-        if (ThreadPool *tp = unwrap(cx, obj))
++-            delete tp;
++-    }
++-
++-  public:
++-    static ThreadPool *unwrap(JSContext *cx, JSObject *obj) {
++-        JS_ASSERT(JS_GET_CLASS(cx, obj) == &jsClass);
++-        return (ThreadPool *) JS_GetPrivate(cx, obj);
++-    }
++-};
++-
++-/*
++- * A Worker is always in one of 4 states, except when it is being initialized
++- * or destroyed, or its lock is held:
++- *   - idle       (!terminated && current == NULL && events.empty())
++- *   - enqueued   (!terminated && current == NULL && !events.empty())
++- *   - busy       (!terminated && current != NULL)
++- *   - terminated (terminated && current == NULL && events.empty())
++- *
++- * Separately, there is a terminateFlag that other threads can set
++- * asynchronously to tell the Worker to terminate.
++- */
++-class Worker : public WorkerParent
++-{
++-  private:
++-    ThreadPool *threadPool;
++-    WorkerParent *parent;
++-    JSObject *object;  // Worker object exposed to parent
++-    JSContext *context;
++-    JSLock *lock;
++-    Queue<Event *, SystemAllocPolicy> events;  // owning pointers to pending events
++-    Event *current;
++-    bool terminated;
++-    int32_t terminateFlag;
++-
++-    static JSClass jsWorkerClass;
++-
++-    Worker()
++-        : threadPool(NULL), parent(NULL), object(NULL),
++-          context(NULL), lock(NULL), current(NULL), terminated(false), terminateFlag(0) {}
++-
++-    bool init(JSContext *parentcx, WorkerParent *parent, JSObject *obj) {
++-        JS_ASSERT(!threadPool && !this->parent && !object && !lock);
++-
++-        if (!initWorkerParent() || !parent->addChild(this))
++-            return false;
++-        threadPool = parent->getThreadPool();
++-        this->parent = parent;
++-        this->object = obj;
++-        lock = JS_NEW_LOCK();
++-        return lock &&
++-               createContext(parentcx, parent) &&
++-               JS_SetPrivate(parentcx, obj, this);
++-    }
++-
++-    bool createContext(JSContext *parentcx, WorkerParent *parent) {
++-        JSRuntime *rt = JS_GetRuntime(parentcx);
++-        context = JS_NewContext(rt, 8192);
++-        if (!context)
++-            return false;
++-
++-        // The Worker has a strong reference to the global; see jsTraceWorker.
++-        // JSOPTION_UNROOTED_GLOBAL ensures that when the worker becomes
++-        // unreachable, it and its global object can be collected. Otherwise
++-        // the cx->globalObject root would keep them both alive forever.
++-        JS_SetOptions(context, JS_GetOptions(parentcx) | JSOPTION_UNROOTED_GLOBAL |
++-                                                         JSOPTION_DONT_REPORT_UNCAUGHT);
++-        JS_SetVersion(context, JS_GetVersion(parentcx));
++-        JS_SetContextPrivate(context, this);
++-        JS_SetOperationCallback(context, jsOperationCallback);
++-        JS_BeginRequest(context);
++-
++-        JSObject *global = threadPool->getHooks()->newGlobalObject(context);
++-        JSObject *post, *proto, *ctor;
++-        if (!global)
++-            goto bad;
++-        JS_SetGlobalObject(context, global);
++-
++-        // Because the Worker is completely isolated from the rest of the
++-        // runtime, and because any pending events on a Worker keep the Worker
++-        // alive, this postMessage function cannot be called after the Worker
++-        // is collected.  Therefore it's safe to stash a pointer (a weak
++-        // reference) to the C++ Worker object in the reserved slot.
++-        post = JS_GetFunctionObject(JS_DefineFunction(context, global, "postMessage",
++-                                                      (JSNative) jsPostMessageToParent, 1, 0));
++-        if (!post || !JS_SetReservedSlot(context, post, 0, PRIVATE_TO_JSVAL(this)))
++-            goto bad;
++-
++-        proto = JS_InitClass(context, global, NULL, &jsWorkerClass, jsConstruct, 1,
++-                             NULL, jsMethods, NULL, NULL);
++-        if (!proto)
++-            goto bad;
++-
++-        ctor = JS_GetConstructor(context, proto);
++-        if (!ctor || !JS_SetReservedSlot(context, ctor, 0, PRIVATE_TO_JSVAL(this)))
++-            goto bad;
++-
++-        JS_EndRequest(context);
++-        JS_ClearContextThread(context);
++-        return true;
++-
++-    bad:
++-        JS_EndRequest(context);
++-        JS_DestroyContext(context);
++-        context = NULL;
++-        return false;
++-    }
++-
++-    static void jsTraceWorker(JSTracer *trc, JSObject *obj) {
++-        JS_ASSERT(JS_GET_CLASS(trc->context, obj) == &jsWorkerClass);
++-        if (Worker *w = (Worker *) JS_GetPrivate(trc->context, obj)) {
++-            w->parent->trace(trc);
++-            w->events.trace(trc);
++-            if (w->current)
++-                w->current->trace(trc);
++-            JS_CALL_OBJECT_TRACER(trc, JS_GetGlobalObject(w->context), "Worker global");
++-        }
++-    }
++-
++-    static void jsFinalize(JSContext *cx, JSObject *obj) {
++-        JS_ASSERT(JS_GET_CLASS(cx, obj) == &jsWorkerClass);
++-        if (Worker *w = (Worker *) JS_GetPrivate(cx, obj))
++-            delete w;
++-    }
++-
++-    static JSBool jsOperationCallback(JSContext *cx) {
++-        Worker *w = (Worker *) JS_GetContextPrivate(cx);
++-        JSAutoSuspendRequest suspend(cx);  // avoid nesting w->lock in a request
++-        return !w->checkTermination();
++-    }
++-
++-    static JSBool jsResolveGlobal(JSContext *cx, JSObject *obj, jsid id, uintN flags,
++-                                  JSObject **objp)
++-    {
++-        JSBool resolved;
++-
++-        if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
++-            return false;
++-        if (resolved)
++-            *objp = obj;
++-
++-        return true;
++-    }
++-
++-    static JSBool jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp);
++-    static JSBool jsPostMessageToChild(JSContext *cx, uintN argc, jsval *vp);
++-    static JSBool jsTerminate(JSContext *cx, uintN argc, jsval *vp);
++-
++-    bool checkTermination() {
++-        AutoLock hold(lock);
++-        return lockedCheckTermination();
++-    }
++-
++-    bool lockedCheckTermination() {
++-        if (terminateFlag || threadPool->isTerminating()) {
++-            terminateSelf();
++-            terminateFlag = 0;
++-        }
++-        return terminated;
++-    }
++-
++-    // Caller must hold the lock.
++-    void terminateSelf() {
++-        terminated = true;
++-        while (!events.empty())
++-            events.pop()->destroy(context);
++-
++-        // Tell the children to shut down too. An arbitrarily silly amount of
++-        // processing could happen before the whole tree is terminated; but
++-        // this way we don't have to worry about blowing the C stack.
++-        for (ChildSet::Enum e(children); !e.empty(); e.popFront())
++-            e.front()->setTerminateFlag();  // note: nesting locks here
++-    }
++-
++-  public:
++-    ~Worker() {
++-        if (parent)
++-            parent->removeChild(this);
++-        dispose();
++-    }
++-
++-    void dispose() {
++-        JS_ASSERT(!current);
++-        while (!events.empty())
++-            events.pop()->destroy(context);
++-        if (lock) {
++-            JS_DESTROY_LOCK(lock);
++-            lock = NULL;
++-        }
++-        if (context) {
++-            JS_SetContextThread(context);
++-            JS_DestroyContextNoGC(context);
++-            context = NULL;
++-        }
++-        object = NULL;
++-
++-        // Do not call parent->removeChild(). This is called either from
++-        // ~Worker, which calls it for us; or from parent->disposeChildren or
++-        // Worker::create, which require that it not be called.
++-        parent = NULL;
++-        disposeChildren();
++-    }
++-
++-    static Worker *create(JSContext *parentcx, WorkerParent *parent,
++-                          JSString *scriptName, JSObject *obj);
++-
++-    JSObject *asObject() { return object; }
++-
++-    JSObject *getGlobal() { return JS_GetGlobalObject(context); }
++-
++-    WorkerParent *getParent() { return parent; }
++-
++-    virtual JSLock *getLock() { return lock; }
++-
++-    virtual ThreadPool *getThreadPool() { return threadPool; }
++-
++-    bool post(Event *event) {
++-        AutoLock hold(lock);
++-        if (terminated)
++-            return false;
++-        if (!current && events.empty() && !threadPool->getWorkerQueue()->post(this))
++-            return false;
++-        return events.push(event);
++-    }
++-
++-    void setTerminateFlag() {
++-        AutoLock hold(lock);
++-        terminateFlag = true;
++-        if (current)
++-            JS_TriggerOperationCallback(context);
++-    }
++-
++-    void processOneEvent();
++-
++-    /* Trace method to be called from C++. */
++-    void trace(JSTracer *trc) {
++-        // Just mark the JSObject. If we haven't already been marked,
++-        // jsTraceWorker will be called, at which point we'll trace referents.
++-        JS_CALL_OBJECT_TRACER(trc, object, "queued Worker");
++-    }
++-
++-    static bool getWorkerParentFromConstructor(JSContext *cx, JSObject *ctor, WorkerParent **p) {
++-        jsval v;
++-        if (!JS_GetReservedSlot(cx, ctor, 0, &v))
++-            return false;
++-        if (JSVAL_IS_VOID(v)) {
++-            // This means ctor is the root Worker constructor (created in
++-            // Worker::initWorkers as opposed to Worker::createContext, which sets up
++-            // Worker sandboxes) and nothing is initialized yet.
++-            if (!JS_GetReservedSlot(cx, ctor, 1, &v))
++-                return false;
++-            ThreadPool *threadPool = (ThreadPool *) JSVAL_TO_PRIVATE(v);
++-            if (!threadPool->start(cx))
++-                return false;
++-            WorkerParent *parent = threadPool->getMainQueue();
++-            if (!JS_SetReservedSlot(cx, ctor, 0, PRIVATE_TO_JSVAL(parent))) {
++-                threadPool->shutdown(cx);
++-                return false;
++-            }
++-            *p = parent;
++-            return true;
++-        }
++-        *p = (WorkerParent *) JSVAL_TO_PRIVATE(v);
++-        return true;
++-    }
++-
++-    static JSBool jsConstruct(JSContext *cx, uintN argc, jsval *vp) {
++-        WorkerParent *parent;
++-        if (!getWorkerParentFromConstructor(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), &parent))
++-            return false;
++-
++-
++-        JSString *scriptName = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
++-        if (!scriptName)
++-            return false;
++-
++-        JSObject *obj = JS_NewObject(cx, &jsWorkerClass, NULL, NULL);
++-        if (!obj || !create(cx, parent, scriptName, obj))
++-            return false;
++-        JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
++-        return true;
++-    }
++-
++-    static JSFunctionSpec jsMethods[3];
++-    static JSFunctionSpec jsStaticMethod[2];
++-
++-    static ThreadPool *initWorkers(JSContext *cx, WorkerHooks *hooks, JSObject *global,
++-                                   JSObject **objp) {
++-        // Create the ThreadPool object and its JSObject wrapper.
++-        ThreadPool *threadPool = ThreadPool::create(cx, hooks);
++-        if (!threadPool)
++-            return NULL;
++-
++-        // Root the ThreadPool JSObject early.
++-        *objp = threadPool->asObject();
++-
++-        // Create the Worker constructor.
++-        JSObject *proto = JS_InitClass(cx, global, NULL, &jsWorkerClass,
++-                                       jsConstruct, 1,
++-                                       NULL, jsMethods, NULL, NULL);
++-        if (!proto)
++-            return NULL;
++-
++-        // Stash a pointer to the ThreadPool in constructor reserved slot 1.
++-        // It will be used later when lazily creating the MainQueue.
++-        JSObject *ctor = JS_GetConstructor(cx, proto);
++-        if (!JS_SetReservedSlot(cx, ctor, 1, PRIVATE_TO_JSVAL(threadPool)))
++-            return NULL;
++-
++-        return threadPool;
++-    }
++-};
++-
++-class InitEvent : public Event
++-{
++-  public:
++-    static InitEvent *create(JSContext *cx, Worker *worker, JSString *scriptName) {
++-        return createEvent<InitEvent>(cx, worker, worker, STRING_TO_JSVAL(scriptName));
++-    }
++-
++-    Result process(JSContext *cx) {
++-        jsval s;
++-        if (!deserializeData(cx, &s))
++-            return fail;
++-        JS_ASSERT(JSVAL_IS_STRING(s));
++-        JSAutoByteString filename(cx, JSVAL_TO_STRING(s));
++-        if (!filename)
++-            return fail;
++-
++-        JSObject *scriptObj = JS_CompileFile(cx, child->getGlobal(), filename.ptr());
++-        if (!scriptObj)
++-            return fail;
++-
++-        AutoValueRooter rval(cx);
++-        JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), scriptObj, Jsvalify(rval.addr()));
++-        return Result(ok);
++-    }
++-};
++-
++-class DownMessageEvent : public Event
++-{
++-  public:
++-    static DownMessageEvent *create(JSContext *cx, Worker *child, jsval data) {
++-        return createEvent<DownMessageEvent>(cx, child, child, data);
++-    }
++-
++-    Result process(JSContext *cx) {
++-        return dispatch(cx, child->getGlobal(), "data", "onmessage", ok);
++-    }
++-};
++-
++-class UpMessageEvent : public Event
++-{
++-  public:
++-    static UpMessageEvent *create(JSContext *cx, Worker *child, jsval data) {
++-        return createEvent<UpMessageEvent>(cx, child->getParent(), child, data);
++-    }
++-
++-    Result process(JSContext *cx) {
++-        return dispatch(cx, child->asObject(), "data", "onmessage", ok);
++-    }
++-};
++-
++-class ErrorEvent : public Event
++-{
++-  public:
++-    static ErrorEvent *create(JSContext *cx, Worker *child) {
++-        JSString *data = NULL;
++-        jsval exc;
++-        if (JS_GetPendingException(cx, &exc)) {
++-            AutoValueRooter tvr(cx, Valueify(exc));
++-            JS_ClearPendingException(cx);
++-
++-            // Determine what error message to put in the error event.
++-            // If exc.message is a string, use that; otherwise use String(exc).
++-            // (This is a little different from what web workers do.)
++-            if (JSVAL_IS_OBJECT(exc)) {
++-                jsval msg;
++-                if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(exc), "message", &msg))
++-                    JS_ClearPendingException(cx);
++-                else if (JSVAL_IS_STRING(msg))
++-                    data = JSVAL_TO_STRING(msg);
++-            }
++-            if (!data) {
++-                data = JS_ValueToString(cx, exc);
++-                if (!data)
++-                    return NULL;
++-            }
++-        }
++-        return createEvent<ErrorEvent>(cx, child->getParent(), child,
++-                                       data ? STRING_TO_JSVAL(data) : JSVAL_VOID);
++-    }
++-
++-    Result process(JSContext *cx) {
++-        return dispatch(cx, child->asObject(), "message", "onerror", forwardToParent);
++-    }
++-};
++-
++-} /* namespace workers */
++-} /* namespace js */
++-
++-using namespace js::workers;
++-
++-void
++-WorkerParent::disposeChildren()
++-{
++-    for (ChildSet::Enum e(children); !e.empty(); e.popFront()) {
++-        e.front()->dispose();
++-        e.removeFront();
++-    }
++-}
++-
++-bool
++-MainQueue::shouldStop()
++-{
++-    // Note: This deliberately nests WorkerQueue::lock in MainQueue::lock.
++-    // Releasing MainQueue::lock would risk a race -- isIdle() could return
++-    // false, but the workers could become idle before we reacquire
++-    // MainQueue::lock and go to sleep, and we would wait on the condvar
++-    // forever.
++-    return closed || threadPool->getWorkerQueue()->isIdle();
++-}
++-
++-void
++-MainQueue::trace(JSTracer *trc)
++-{
++-     JS_CALL_OBJECT_TRACER(trc, threadPool->asObject(), "MainQueue");
++-}
++-
++-void
++-WorkerQueue::work() {
++-    AutoLock hold(lock);
++-
++-    Worker *w;
++-    while (take(&w)) {  // can block outside the mutex
++-        JS_RELEASE_LOCK(lock);
++-        w->processOneEvent();     // enters request on w->context
++-        JS_ACQUIRE_LOCK(lock);
++-        drop(w);
++-
++-        if (lockedIsIdle()) {
++-            JS_RELEASE_LOCK(lock);
++-            main->wake();
++-            JS_ACQUIRE_LOCK(lock);
++-        }
++-    }
++-}
++-
++-const bool mswin =
++-#ifdef XP_WIN
++-    true
++-#else
++-    false
++-#endif
++-    ;
++-
++-template <class Ch> bool
++-IsAbsolute(const Ch *filename)
++-{
++-    return filename[0] == '/' ||
++-           (mswin && (filename[0] == '\\' || (filename[0] != '\0' && filename[1] == ':')));
++-}
++-
++-// Note: base is a filename, not a directory name.
++-static JSString *
++-ResolveRelativePath(JSContext *cx, const char *base, JSString *filename)
++-{
++-    size_t fileLen = JS_GetStringLength(filename);
++-    const jschar *fileChars = JS_GetStringCharsZ(cx, filename);
++-    if (!fileChars)
++-        return NULL;
++-
++-    if (IsAbsolute(fileChars))
++-        return filename;
++-
++-    // Strip off the filename part of base.
++-    size_t dirLen = -1;
++-    for (size_t i = 0; base[i]; i++) {
++-        if (base[i] == '/' || (mswin && base[i] == '\\'))
++-            dirLen = i;
++-    }
++-
++-    // If base is relative and contains no directories, use filename unchanged.
++-    if (!IsAbsolute(base) && dirLen == (size_t) -1)
++-        return filename;
++-
++-    // Otherwise return base[:dirLen + 1] + filename.
++-    js::Vector<jschar, 0, js::ContextAllocPolicy> result(cx);
++-    size_t nchars;
++-    if (!JS_DecodeBytes(cx, base, dirLen + 1, NULL, &nchars))
++-        return NULL;
++-    if (!result.reserve(dirLen + 1 + fileLen)) {
++-        JS_ReportOutOfMemory(cx);
++-        return NULL;
++-    }
++-    JS_ALWAYS_TRUE(result.resize(dirLen + 1));
++-    if (!JS_DecodeBytes(cx, base, dirLen + 1, result.begin(), &nchars))
++-        return NULL;
++-    JS_ALWAYS_TRUE(result.append(fileChars, fileLen));
++-    return JS_NewUCStringCopyN(cx, result.begin(), result.length());
++-}
++-
++-Worker *
++-Worker::create(JSContext *parentcx, WorkerParent *parent, JSString *scriptName, JSObject *obj)
++-{
++-    Worker *w = new Worker();
++-    if (!w || !w->init(parentcx, parent, obj)) {
++-        delete w;
++-        return NULL;
++-    }
++-
++-    JSStackFrame *frame = JS_GetScriptedCaller(parentcx, NULL);
++-    const char *base = JS_GetScriptFilename(parentcx, JS_GetFrameScript(parentcx, frame));
++-    JSString *scriptPath = ResolveRelativePath(parentcx, base, scriptName);
++-    if (!scriptPath)
++-        return NULL;
++-
++-    // Post an InitEvent to run the initialization script.
++-    Event *event = InitEvent::create(parentcx, w, scriptPath);
++-    if (!event)
++-        return NULL;
++-    if (!w->events.push(event) || !w->threadPool->getWorkerQueue()->post(w)) {
++-        event->destroy(parentcx);
++-        JS_ReportOutOfMemory(parentcx);
++-        w->dispose();
++-        return NULL;
++-    }
++-    return w;
++-}
++-
++-void
++-Worker::processOneEvent()
++-{
++-    Event *event;
++-    {
++-        AutoLock hold1(lock);
++-        if (lockedCheckTermination() || events.empty())
++-            return;
++-
++-        event = current = events.pop();
++-    }
++-
++-    JS_SetContextThread(context);
++-    JS_SetNativeStackQuota(context, gMaxStackSize);
++-
++-    Event::Result result;
++-    {
++-        JSAutoRequest req(context);
++-        result = event->process(context);
++-    }
++-
++-    // Note: we have to leave the above request before calling parent->post or
++-    // checkTermination, both of which acquire locks.
++-    if (result == Event::forwardToParent) {
++-        event->setChildAndRecipient(this, parent);
++-        if (parent->post(event)) {
++-            event = NULL;  // to prevent it from being deleted below
++-        } else {
++-            JS_ReportOutOfMemory(context);
++-            result = Event::fail;
++-        }
++-    }
++-    if (result == Event::fail && !checkTermination()) {
++-        JSAutoRequest req(context);
++-        Event *err = ErrorEvent::create(context, this);
++-        if (err && !parent->post(err)) {
++-            JS_ReportOutOfMemory(context);
++-            err->destroy(context);
++-            err = NULL;
++-        }
++-        if (!err) {
++-            // FIXME - out of memory, probably should panic
++-        }
++-    }
++-
++-    if (event)
++-        event->destroy(context);
++-    JS_ClearContextThread(context);
++-
++-    {
++-        AutoLock hold2(lock);
++-        current = NULL;
++-        if (!lockedCheckTermination() && !events.empty()) {
++-            // Re-enqueue this worker. OOM here effectively kills the worker.
++-            if (!threadPool->getWorkerQueue()->post(this))
++-                JS_ReportOutOfMemory(context);
++-        }
++-    }
++-}
++-
++-JSBool
++-Worker::jsPostMessageToParent(JSContext *cx, uintN argc, jsval *vp)
++-{
++-    jsval workerval;
++-    if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &workerval))
++-        return false;
++-    Worker *w = (Worker *) JSVAL_TO_PRIVATE(workerval);
++-
++-    {
++-        JSAutoSuspendRequest suspend(cx);  // avoid nesting w->lock in a request
++-        if (w->checkTermination())
++-            return false;
++-    }
++-
++-    jsval data = argc > 0 ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
++-    Event *event = UpMessageEvent::create(cx, w, data);
++-    if (!event)
++-        return false;
++-    if (!w->parent->post(event)) {
++-        event->destroy(cx);
++-        JS_ReportOutOfMemory(cx);
++-        return false;
++-    }
++-    JS_SET_RVAL(cx, vp, JSVAL_VOID);
++-    return true;
++-}
++-
++-JSBool
++-Worker::jsPostMessageToChild(JSContext *cx, uintN argc, jsval *vp)
++-{
++-    JSObject *workerobj = JS_THIS_OBJECT(cx, vp);
++-    if (!workerobj)
++-        return false;
++-    Worker *w = (Worker *) JS_GetInstancePrivate(cx, workerobj, &jsWorkerClass, JS_ARGV(cx, vp));
++-    if (!w) {
++-        if (!JS_IsExceptionPending(cx))
++-            JS_ReportError(cx, "Worker was shut down");
++-        return false;
++-    }
++-    
++-    jsval data = argc > 0 ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
++-    Event *event = DownMessageEvent::create(cx, w, data);
++-    if (!event)
++-        return false;
++-    if (!w->post(event)) {
++-        JS_ReportOutOfMemory(cx);
++-        return false;
++-    }
++-    JS_SET_RVAL(cx, vp, JSVAL_VOID);
++-    return true;
++-}
++-
++-JSBool
++-Worker::jsTerminate(JSContext *cx, uintN argc, jsval *vp)
++-{
++-    JS_SET_RVAL(cx, vp, JSVAL_VOID);
++-
++-    JSObject *workerobj = JS_THIS_OBJECT(cx, vp);
++-    if (!workerobj)
++-        return false;
++-    Worker *w = (Worker *) JS_GetInstancePrivate(cx, workerobj, &jsWorkerClass, JS_ARGV(cx, vp));
++-    if (!w)
++-        return !JS_IsExceptionPending(cx);  // ok to terminate twice
++-
++-    JSAutoSuspendRequest suspend(cx);
++-    w->setTerminateFlag();
++-    return true;
++-}
++-
++-void
++-Event::trace(JSTracer *trc)
++-{
++-    if (recipient)
++-        recipient->trace(trc);
++-    if (child)
++-        JS_CALL_OBJECT_TRACER(trc, child->asObject(), "worker");
++-}
++-
++-JSClass ThreadPool::jsClass = {
++-    "ThreadPool", JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE,
++-    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
++-    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, jsFinalize,
++-    NULL, NULL, NULL, NULL,
++-    NULL, NULL, JS_CLASS_TRACE(jsTraceThreadPool), NULL
++-};
++-
++-JSClass Worker::jsWorkerClass = {
++-    "Worker", JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE,
++-    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
++-    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, jsFinalize,
++-    NULL, NULL, NULL, NULL,
++-    NULL, NULL, JS_CLASS_TRACE(jsTraceWorker), NULL
++-};
++-
++-JSFunctionSpec Worker::jsMethods[3] = {
++-    JS_FN("postMessage", Worker::jsPostMessageToChild, 1, 0),
++-    JS_FN("terminate", Worker::jsTerminate, 0, 0),
++-    JS_FS_END
++-};
++-
++-ThreadPool *
++-js::workers::init(JSContext *cx, WorkerHooks *hooks, JSObject *global, JSObject **rootp)
++-{
++-    return Worker::initWorkers(cx, hooks, global, rootp);
++-}
++-
++-void
++-js::workers::terminateAll(JSRuntime *rt, ThreadPool *tp)
++-{
++-    tp->terminateAll(rt);
++-}
++-
++-void
++-js::workers::finish(JSContext *cx, ThreadPool *tp)
++-{
++-    if (MainQueue *mq = tp->getMainQueue()) {
++-        JS_ALWAYS_TRUE(mq->mainThreadWork(cx, true));
++-        tp->shutdown(cx);
++-    }
++-}
++-
++-#endif /* JS_THREADSAFE */
+diff -ruN deps.orig/mozilla/js/src/shell/jsworkers.h deps/mozilla/js/src/shell/jsworkers.h
+--- deps.orig/mozilla/js/src/shell/jsworkers.h	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/shell/jsworkers.h	2014-09-23 07:59:03.000000000 +0400
+@@ -1,93 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+- * vim: set ts=8 sw=4 et tw=99:
+- *
+- * ***** 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 JavaScript shell workers.
+- *
+- * The Initial Developer of the Original Code is
+- * Mozilla Corporation.
+- * Portions created by the Initial Developer are Copyright (C) 2010
+- * the Initial Developer. All Rights Reserved.
+- *
+- * Contributor(s):
+- *   Jason Orendorff <jorendorff@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 ***** */
+-
+-#ifndef jsworkers_h___
+-#define jsworkers_h___
+-
+-#ifdef JS_THREADSAFE
+-
+-#include "jsapi.h"
+-
+-/*
+- * Workers for the JS shell.
+- *
+- * Note: The real implementation of DOM Workers is in dom/src/threads.
+- */
+-namespace js {
+-    namespace workers {
+-        class ThreadPool;
+-
+-        class WorkerHooks {
+-        public:
+-            virtual JSObject *newGlobalObject(JSContext *cx) = 0;
+-            virtual ~WorkerHooks() {}
+-        };
+-
+-        /*
+-	 * Initialize workers. This defines the Worker constructor on global.
+-	 * Requires request. rootp must point to a GC root.
+-	 *
+-	 * On success, *rootp receives a pointer to an object, and init returns
+-         * a non-null value. The caller must keep the object rooted and must
+-         * pass it to js::workers::finish later.
+-	 */
+-        ThreadPool *init(JSContext *cx, WorkerHooks *hooks, JSObject *global, JSObject **rootp);
+-
+-        /* Asynchronously signal for all workers to terminate.
+-         *
+-         * Call this before calling finish() to shut down without waiting for
+-         * all messages to be proceesed.
+-         */
+-        void terminateAll(JSRuntime *rt, ThreadPool *tp);
+-
+-	/*
+-	 * Finish running any workers, shut down the thread pool, and free all
+-	 * resources associated with workers. The application must call this
+-	 * before shutting down the runtime, and not during GC.
+-	 *
+-	 * Requires request.
+-	 */
+-	void finish(JSContext *cx, ThreadPool *tp);
+-    }
+-}
+-
+-#endif /* JS_THREADSAFE */
+-
+-#endif /* jsworkers_h___ */
+diff -ruN deps.orig/mozilla/js/src/tests/browser.js deps/mozilla/js/src/tests/browser.js
+--- deps.orig/mozilla/js/src/tests/browser.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/browser.js	2014-09-23 07:59:03.000000000 +0400
+@@ -767,17 +767,6 @@
+   document.write(s);
+ }
+ 
+-var JSTest = {
+-  waitForExplicitFinish: function () {
+-    gDelayTestDriverEnd = true;
+-  },
+-
+-  testFinished: function () {
+-    gDelayTestDriverEnd = false;
+-    jsTestDriverEnd();
+-  }
+-};
+-
+ function jsTestDriverEnd()
+ {
+   // gDelayTestDriverEnd is used to
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/jstests.list deps/mozilla/js/src/tests/js1_8_5/extensions/jstests.list
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/jstests.list	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/jstests.list	2014-09-23 07:59:03.000000000 +0400
+@@ -1,13 +1,6 @@
+ url-prefix ../../jsreftest.html?test=js1_8_5/extensions/
+ script typedarray.js
+ script typedarray-prototype.js
+-skip-if(!xulRuntime.shell) script worker-error.js  # these tests sometimes hang in browser, bug 559954, bug 562333
+-skip-if(!xulRuntime.shell) script worker-error-propagation.js
+-skip-if(!xulRuntime.shell) script worker-fib.js
+-skip-if(!xulRuntime.shell) script worker-init.js
+-skip-if(!xulRuntime.shell) script worker-simple.js
+-skip-if(!xulRuntime.shell) script worker-terminate.js
+-skip-if(!xulRuntime.shell) script worker-timeout.js
+ script scripted-proxies.js
+ script array-length-protochange.js
+ script parseInt-octal.js
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,9 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-function onmessage(event) {
+-    throw new Error("fail");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,16 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-function onmessage(event) {
+-    var n = +event.data;
+-    if (n == 0)
+-        throw new Error("boom");
+-    var w = new Worker(workerDir + "worker-error-propagation-child.js");
+-    w.onmessage = function (event) { postMessage(event.data); };
+-    // No w.onerror here. We are testing error propagation when it is absent.
+-    w.postMessage(n - 1 + "");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error-propagation.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,20 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-if (typeof Worker != 'undefined') {
+-    JSTest.waitForExplicitFinish();
+-    var w = Worker(workerDir + "worker-error-propagation-child.js");
+-    var errors = 0;
+-    w.onmessage = function () { throw new Error("no reply expected"); };
+-    w.onerror = function (event) {
+-        reportCompare("string", typeof event.message, "typeof event.message");
+-        JSTest.testFinished();
+-    };
+-    w.postMessage("5");
+-} else {
+-    reportCompare(0, 0, " PASSED! Test skipped. Shell workers required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-error.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,21 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-if (typeof Worker != 'undefined') {
+-    JSTest.waitForExplicitFinish();
+-
+-    // The script throws new Error("fail") on first message.
+-    var w = Worker(workerDir + "worker-error-child.js");
+-    var a = [];
+-    w.onerror = function (event) {
+-        reportCompare("fail", event.message, "worker-error");
+-        JSTest.testFinished();
+-    };
+-    w.postMessage("hello");
+-} else {
+-    reportCompare(0, 0, "Test skipped. Shell workers required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,27 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-function onmessage(event) {
+-    var a = event.data.split(/\t/);
+-    var n = Number(a[0]);
+-    var workerDir = a[1];
+-
+-    if (n <= 1) {
+-        postMessage("" + n);
+-    } else {
+-        var w1 = new Worker(workerDir + "worker-fib-child.js"),
+-            w2 = new Worker(workerDir + "worker-fib-child.js");
+-        var a = [];
+-        w1.onmessage = w2.onmessage = function(event) {
+-            a.push(+event.data);
+-            if (a.length == 2)
+-                postMessage(a[0] + a[1] + "");
+-        };
+-        w1.postMessage(n - 1 + "\t" + workerDir);
+-        w2.postMessage(n - 2 + "\t" + workerDir);
+-    }
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-fib.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,18 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-if (typeof Worker != 'undefined') {
+-    JSTest.waitForExplicitFinish();
+-    var w = Worker(workerDir + "worker-fib-child.js");
+-    w.onmessage = function (event) {
+-        reportCompare("55", event.data, "worker-fib");
+-        JSTest.testFinished();
+-    };
+-    w.postMessage("10\t" + workerDir); // 0 1 1 2 3 5 8 13 21 34 55
+-} else {
+-    reportCompare(0, 0, "Test skipped. Shell workers required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,8 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-postMessage('do your worst');
+-for (;;) ;
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-init.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,19 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-if (typeof Worker != 'undefined') {
+-    JSTest.waitForExplicitFinish();
+-    // Messages sent during initialization are a corner case, but in any case
+-    // they should be delivered (no waiting until initialization is complete).
+-    var w = new Worker(workerDir + "worker-init-child.js"); // posts a message, then loops forever
+-    w.onmessage = function (event) {
+-        reportCompare(0, 0, "worker-init");
+-        JSTest.testFinished();
+-    };
+-} else {
+-    reportCompare(0, 0, "Test skipped. Shell workers required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,8 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-onmessage = function (event) { postMessage(event.data); };
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-simple.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,20 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-if (typeof Worker != 'undefined') {
+-    JSTest.waitForExplicitFinish();
+-    var w = new Worker(workerDir + "worker-simple-child.js");
+-    var a = [];
+-    w.onmessage = function (event) {
+-        a.push(event.data);
+-        reportCompare(0, 0, "worker-simple");
+-        JSTest.testFinished();
+-    };
+-    w.postMessage("hello");
+-} else {
+-    reportCompare(0, 0, "Test skipped. Shell workers required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,13 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-onmessage = function (event) {
+-    var workerDir = event.message;
+-    var child = new Worker(workerDir + 'worker-terminate-iloop.js'); // loops forever
+-    child.terminate();
+-    postMessage("killed");
+-};
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate-iloop.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,9 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-for (;;)
+-    ;
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-terminate.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,37 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff <jorendorff@mozilla.com>
+- */
+-
+-if (typeof Worker != 'undefined') {
+-    JSTest.waitForExplicitFinish();
+-
+-    // This tests that a parent worker can terminate a child.  We run the test
+-    // several times serially. If terminate() doesn't work, the runaway Workers
+-    // will soon outnumber the number of threads in the thread pool, and we
+-    // will deadlock.
+-    var i = 0;
+-
+-    function next() {
+-        if (++i == 10) {
+-            reportCompare(0, 0, "worker-terminate");
+-            JSTest.testFinished();
+-            return;
+-        }
+-
+-        var w = new Worker(workerDir + "worker-terminate-child.js");
+-        w.onmessage = function (event) {
+-            reportCompare("killed", event.data, "killed runaway worker #" + i);
+-            next();
+-        };
+-        w.onerror = function (event) {
+-            reportCompare(0, 1, "Got error: " + event.message);
+-        };
+-        w.postMessage(workerDir);
+-    }
+-    next();
+-} else {
+-    reportCompare(0, 0, "Test skipped. Shell workers required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout-child.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,9 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff
+- */
+-
+-for (;;)
+-    ;
+diff -ruN deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js
+--- deps.orig/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/js1_8_5/extensions/worker-timeout.js	2014-09-23 07:59:03.000000000 +0400
+@@ -1,18 +0,0 @@
+-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/*
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/licenses/publicdomain/
+- * Contributor: Jason Orendorff
+- */
+-
+-if (typeof timeout == 'function' && typeof Worker != 'undefined') {
+-    // We don't actually ever call JSTest.testFinished(); instead we
+-    // time out and exit the shell with exit code 6.
+-    JSTest.waitForExplicitFinish();
+-    expectExitCode(6);
+-    timeout(1.0);
+-    for (var i = 0; i < 5; i++)
+-        new Worker(workerDir + "worker-timeout-child.js"); // just loops forever
+-} else {
+-    reportCompare(0, 0, "Test skipped. Shell workers and timeout required.");
+-}
+diff -ruN deps.orig/mozilla/js/src/tests/shell.js deps/mozilla/js/src/tests/shell.js
+--- deps.orig/mozilla/js/src/tests/shell.js	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/tests/shell.js	2014-09-23 07:59:03.000000000 +0400
+@@ -833,18 +833,6 @@
+   }
+ }
+ 
+-var JSTest = {
+-  waitForExplicitFinish: function () {
+-    gDelayTestDriverEnd = true;
+-  },
+-
+-  testFinished: function () {
+-    gDelayTestDriverEnd = false;
+-    jsTestDriverEnd();
+-    quit();
+-  }
+-};
+-
+ function jsTestDriverEnd()
+ {
+   // gDelayTestDriverEnd is used to
diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_configure oolite/files/patch-deps_mozilla_js_src_configure
--- oolite.orig/files/patch-deps_mozilla_js_src_configure	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-deps_mozilla_js_src_configure	2014-09-24 12:46:54.000000000 +0400
@@ -0,0 +1,12 @@
+--- deps/mozilla/js/src/configure.orig	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/configure	2014-09-24 04:01:12.000000000 +0400
+@@ -9547,7 +9547,8 @@
+ 
+ echo "$ac_t""$ac_cv_have_visibility_builtin_bug" 1>&6
+         if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \
+-                "$ac_cv_have_visibility_class_bug" = "no"; then
++                "$ac_cv_have_visibility_class_bug" = "no" -a \
++		"$OS_ARCH" != "FreeBSD" ; then
+           VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h'
+           WRAP_SYSTEM_INCLUDES=1
+           STL_FLAGS='-I$(DIST)/stl_wrappers'
diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_configure.in oolite/files/patch-deps_mozilla_js_src_configure.in
--- oolite.orig/files/patch-deps_mozilla_js_src_configure.in	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-deps_mozilla_js_src_configure.in	2014-09-24 12:47:08.000000000 +0400
@@ -0,0 +1,12 @@
+--- deps/mozilla/js/src/configure.in.orig	2014-06-30 12:54:39.000000000 +0400
++++ deps/mozilla/js/src/configure.in	2014-09-23 08:13:19.000000000 +0400
+@@ -3378,7 +3378,8 @@
+                        rm -f conftest.{c,S}
+                        ])
+         if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \
+-                "$ac_cv_have_visibility_class_bug" = "no"; then
++                "$ac_cv_have_visibility_class_bug" = "no" -a \
++		"$OS_ARCH" != "FreeBSD" ; then
+           VISIBILITY_FLAGS='-I$(DIST)/system_wrappers_js -include $(topsrcdir)/config/gcc_hidden.h'
+           WRAP_SYSTEM_INCLUDES=1
+           STL_FLAGS='-I$(DIST)/stl_wrappers'
diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_jsscript.h oolite/files/patch-deps_mozilla_js_src_jsscript.h
--- oolite.orig/files/patch-deps_mozilla_js_src_jsscript.h	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-deps_mozilla_js_src_jsscript.h	2014-09-23 08:18:20.000000000 +0400
@@ -0,0 +1,48 @@
+# HG changeset patch
+# User Ehsan Akhgari <ehsan@mozilla.com>
+# Date 1308340787 14400
+# Node ID c0e8643e8e60d1c98bff30c78e034f991f75c191
+# Parent  284ebc48b2cb8e35dc04482ede700e717d8d214f
+Bug 662962 - Silence the clang warnings issued because of alignment requirements increase when compiling jsscript.h; r=Waldo
+
+--- deps/mozilla/js/src/jsscript.h.orig	2011-04-01 06:08:36.000000000 +1100
++++ deps/mozilla/js/src/jsscript.h	2013-05-26 00:23:16.202260566 +1000
+@@ -496,32 +496,32 @@
+ 
+     JSObjectArray *objects() {
+         JS_ASSERT(isValidOffset(objectsOffset));
+-        return (JSObjectArray *)((uint8 *) (this + 1) + objectsOffset);
++        return reinterpret_cast<JSObjectArray *>(uintptr_t(this + 1) + objectsOffset);
+     }
+ 
+     JSUpvarArray *upvars() {
+         JS_ASSERT(isValidOffset(upvarsOffset));
+-        return (JSUpvarArray *) ((uint8 *) (this + 1) + upvarsOffset);
++        return reinterpret_cast<JSUpvarArray *>(uintptr_t(this + 1) + upvarsOffset);
+     }
+ 
+     JSObjectArray *regexps() {
+         JS_ASSERT(isValidOffset(regexpsOffset));
+-        return (JSObjectArray *) ((uint8 *) (this + 1) + regexpsOffset);
++        return reinterpret_cast<JSObjectArray *>(uintptr_t(this + 1) + regexpsOffset);
+     }
+ 
+     JSTryNoteArray *trynotes() {
+         JS_ASSERT(isValidOffset(trynotesOffset));
+-        return (JSTryNoteArray *) ((uint8 *) (this + 1) + trynotesOffset);
++        return reinterpret_cast<JSTryNoteArray *>(uintptr_t(this + 1) + trynotesOffset);
+     }
+ 
+     js::GlobalSlotArray *globals() {
+         JS_ASSERT(isValidOffset(globalsOffset));
+-        return (js::GlobalSlotArray *) ((uint8 *) (this + 1) + globalsOffset);
++        return reinterpret_cast<js::GlobalSlotArray *>(uintptr_t(this + 1) + globalsOffset);
+     }
+ 
+     JSConstArray *consts() {
+         JS_ASSERT(isValidOffset(constOffset));
+-        return (JSConstArray *) ((uint8 *) (this + 1) + constOffset);
++        return reinterpret_cast<JSConstArray *>(uintptr_t(this + 1) + constOffset);
+     }
+ 
+     JSAtom *getAtom(size_t index) {
diff -ruN oolite.orig/files/patch-deps_mozilla_js_src_jsstr.cpp oolite/files/patch-deps_mozilla_js_src_jsstr.cpp
--- oolite.orig/files/patch-deps_mozilla_js_src_jsstr.cpp	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-deps_mozilla_js_src_jsstr.cpp	2014-09-23 08:19:30.000000000 +0400
@@ -0,0 +1,36 @@
+# HG changeset patch
+# User Ehsan Akhgari <ehsan@mozilla.com>
+# Date 1308517488 14400
+# Node ID 284ebc48b2cb8e35dc04482ede700e717d8d214f
+# Parent  cecc5adfc44068fb6f11b9baa78cb5fddc100b27
+Bug 662961 - Silence the clang warnings issued because of alignment requirements increase when compiling jsstr.cpp; r=Waldo
+
+--- deps/mozilla/js/src/jsstr.cpp.orig	2013-05-26 00:44:33.383765764 +1000
++++ deps/mozilla/js/src/jsstr.cpp	2013-05-26 00:46:35.842211859 +1000
+@@ -3147,7 +3147,7 @@
+  */
+ #define R(c) {                                                                \
+     BUILD_LENGTH_AND_FLAGS(1, JSString::FLAT | JSString::ATOMIZED),           \
+-    { (jschar *)(((char *)(unitStringTable + (c))) +                          \
++    { (jschar *)(uintptr_t(unitStringTable + (c)) +                           \
+       offsetof(JSString, inlineStorage)) },                                   \
+     { {(c), 0x00} } }
+ 
+@@ -3207,7 +3207,7 @@
+  */
+ #define R(c) {                                                                \
+     BUILD_LENGTH_AND_FLAGS(2, JSString::FLAT | JSString::ATOMIZED),           \
+-    { (jschar *)(((char *)(length2StringTable + (c))) +                       \
++    { (jschar *)(uintptr_t(length2StringTable + (c)) +                        \
+       offsetof(JSString, inlineStorage)) },                                   \
+     { {FROM_SMALL_CHAR((c) >> 6), FROM_SMALL_CHAR((c) & 0x3F), 0x00} } }
+ 
+@@ -3240,7 +3240,7 @@
+  */
+ #define R(c) {                                                                \
+     BUILD_LENGTH_AND_FLAGS(3, JSString::FLAT | JSString::ATOMIZED),           \
+-    { (jschar *)(((char *)(hundredStringTable + ((c) - 100))) +               \
++    { (jschar *)(uintptr_t(hundredStringTable + ((c) - 100)) +                \
+       offsetof(JSString, inlineStorage)) },                                   \
+     { {((c) / 100) + '0', ((c) / 10 % 10) + '0', ((c) % 10) + '0', 0x00} } }
+ 
diff -ruN oolite.orig/files/patch-src_Core_NSFileManagerOOExtensions.h oolite/files/patch-src_Core_NSFileManagerOOExtensions.h
--- oolite.orig/files/patch-src_Core_NSFileManagerOOExtensions.h	2014-01-22 21:40:44.000000000 +0400
+++ oolite/files/patch-src_Core_NSFileManagerOOExtensions.h	1970-01-01 03:00:00.000000000 +0300
@@ -1,11 +0,0 @@
---- src/Core/NSFileManagerOOExtensions.h.orig	2012-04-18 09:43:45.361891055 +0300
-+++ src/Core/NSFileManagerOOExtensions.h	2012-04-18 09:44:08.916890086 +0300
-@@ -28,7 +28,7 @@ MA 02110-1301, USA.
- 
- #import <Foundation/Foundation.h>
- 
--#define SAVEDIR "oolite-saves"
-+#define SAVEDIR ".oolite-saves"
- 
- #if OOLITE_SDL
- #define SNAPSHOTDIR "snapshots"
diff -ruN oolite.orig/files/patch-src_Core_OOMaths.h oolite/files/patch-src_Core_OOMaths.h
--- oolite.orig/files/patch-src_Core_OOMaths.h	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-src_Core_OOMaths.h	2014-10-14 07:21:25.000000000 +0400
@@ -0,0 +1,12 @@
+--- src/Core/OOMaths.h.orig	2014-06-30 12:50:36.000000000 +0400
++++ src/Core/OOMaths.h	2014-10-14 07:20:31.000000000 +0400
+@@ -48,7 +48,8 @@
+ #endif
+ 
+ #include "OOFunctionAttributes.h"
+-#include <tgmath.h>
++#include <complex.h>
++#include <math.h>
+ #include <stdbool.h>
+ #include <stdlib.h>
+ #include <stdint.h>
diff -ruN oolite.orig/files/patch-src_Core_OOOXZManager.m oolite/files/patch-src_Core_OOOXZManager.m
--- oolite.orig/files/patch-src_Core_OOOXZManager.m	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-src_Core_OOOXZManager.m	2014-09-25 08:46:28.000000000 +0400
@@ -0,0 +1,49 @@
+--- src/Core/OOOXZManager.m.orig	2014-06-30 12:50:36.000000000 +0400
++++ src/Core/OOOXZManager.m	2014-09-25 08:46:25.000000000 +0400
+@@ -215,13 +215,45 @@
+ 	}
+ 	if (!exists)
+ 	{
++#if OOLITE_MAC_OS_X
+ 		if (![fmgr oo_createDirectoryAtPath:path attributes:nil])
+ 		{
+ 			OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path);
+ 			return NO;
+ 		}
++#else
++		NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES);
++		NSString *appPath = [paths objectAtIndex:0];
++		if (appPath == nil)
++		{
++			OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path);
++			return NO;
++		}
++		else
++		{
++			if (![fmgr fileExistsAtPath:appPath] && ![fmgr oo_createDirectoryAtPath:appPath attributes:nil])
++			{
++				OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path);
++				return NO;
++			}
++			appPath = [appPath stringByAppendingPathComponent:@"Oolite"];
++			if (![fmgr fileExistsAtPath:appPath] && ![fmgr oo_createDirectoryAtPath:appPath attributes:nil])
++			{
++				OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path);
++				return NO;
++			}
++			/* GNUStep uses "ApplicationSupport" rather than "Application
++			 * Support" so match convention by not putting a space in the
++			 * path either */
++			appPath = [appPath stringByAppendingPathComponent:@"ManagedAddOns"];
++			if (![fmgr fileExistsAtPath:appPath] && ![fmgr oo_createDirectoryAtPath:appPath attributes:nil])
++			{
++				OOLog(kOOOXZErrorLog, @"Could not create folder %@.", path);
++				return NO;
++			}
++		}
++#endif
+ 	}
+-	
+ 	return YES;
+ }
+ 
diff -ruN oolite.orig/files/patch-src_Core_OOPointMaths.h oolite/files/patch-src_Core_OOPointMaths.h
--- oolite.orig/files/patch-src_Core_OOPointMaths.h	1970-01-01 03:00:00.000000000 +0300
+++ oolite/files/patch-src_Core_OOPointMaths.h	2014-10-16 13:52:18.000000000 +0400
@@ -0,0 +1,10 @@
+--- src/Core/OOPointMaths.h.orig	2014-06-30 12:50:36.000000000 +0400
++++ src/Core/OOPointMaths.h	2014-10-16 13:51:36.000000000 +0400
+@@ -1,5 +1,6 @@
+ #import "OOFunctionAttributes.h"
+-#include <tgmath.h>
++#include <complex.h>
++#include <math.h>
+ 
+ 
+ // Utilities for working with NSPoints as 2D vectors.
diff -ruN oolite.orig/files/pkg-message.in oolite/files/pkg-message.in
--- oolite.orig/files/pkg-message.in	2014-01-22 19:52:06.000000000 +0400
+++ oolite/files/pkg-message.in	1970-01-01 03:00:00.000000000 +0300
@@ -1,16 +0,0 @@
-************************************ NOTE *************************************
-
-If you are not a regular user of GNUstep environment, please follow these
-advice to run oolite:
-
-1. Make sure that necessary GNUstep daemons are running before starting oolite.
-   Usually they are started at boot-time by %%LOCALBASE%%/etc/rc.d/GNUstep.sh
-
-2. To start the game first setup GNUstep environment and then execute 
-   "openapp oolite" command.
-   The environment is set by doing (depending on your shell) either
-   . %%PREFIX%%/System/Library/Makefiles/GNUstep.sh
-   or
-   source %%PREFIX%%/System/Library/Makefiles/GNUstep.csh
-
-*******************************************************************************
diff -ruN oolite.orig/pkg-descr oolite/pkg-descr
--- oolite.orig/pkg-descr	2014-01-22 19:44:51.000000000 +0400
+++ oolite/pkg-descr	2014-09-24 09:24:30.000000000 +0400
@@ -6,9 +6,7 @@
 The game is expandable, and numerous expansion packs already exist. New ships
 and new missions are available for download.
 
-You can find a first-flight tutorial here:
-http://oolite.aegidian.org/tutorial/
+You can find the getting started page here:
+http://www.oolite.org/starting/
 
-LICENSE: CCL Attribution-Noncommercial-Share Alike 2.0 Generic
-
-WWW: http://oolite-linux.berlios.de/
+WWW: http://www.oolite.org
diff -ruN oolite.orig/pkg-plist oolite/pkg-plist
--- oolite.orig/pkg-plist	2014-01-22 19:16:56.000000000 +0400
+++ oolite/pkg-plist	1970-01-01 03:00:00.000000000 +0300
@@ -1,278 +0,0 @@
-GNUstep/Local/Applications/oolite.app/Resources/AIReference.html
-GNUstep/Local/Applications/oolite.app/Resources/AIs/buoyAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/collectLootAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/delayedReactToAttackAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/dockingAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/dumbAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/enteringPirateAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/enteringTraderAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/escortAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/exitingTraderAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/fallingShuttleAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/fttAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/gotoWaypointAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/hardMissileAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/homeAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/interceptAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/minerAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/missileAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/nullAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/oolite-constrictor-AI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/oolite-player-AI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/pirateAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/planetPatrolAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/policeInterceptAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/receiveDockingAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/risingShuttleAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/rockHermitAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/route1patrolAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/route1traderAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/route2patrolAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/route2sunskimAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/scavengerAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/stationAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/sunSkimExitAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/thargletAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/thargoidAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/timebombAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/AIs/traderInterceptAI.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/autoAImap.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/characters.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/commodities.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/crosshairs.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/customsounds.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/demoships.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/descriptions.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/equipment.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/gpu-settings.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/hud-small.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/hud.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/illegal_goods.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/javascript-errors.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/keyconfig.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/logcontrol.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/material-defaults.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/missiontext.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/nebulatextures.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/oolite-font.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/pirate-victim-roles.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/planetinfo.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/screenbackgrounds.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/script-patches.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/shipdata-overrides.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/shipdata.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/shipyard.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/speech_pronunciation_guide.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/startextures.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/verifyOXP.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/whitelist.plist
-GNUstep/Local/Applications/oolite.app/Resources/Config/world-scripts.plist
-GNUstep/Local/Applications/oolite.app/Resources/Images/WMicon.bmp
-GNUstep/Local/Applications/oolite.app/Resources/Images/oolite-long-range-chart.png
-GNUstep/Local/Applications/oolite.app/Resources/Images/oolite-nova-system.png
-GNUstep/Local/Applications/oolite.app/Resources/Images/oolite-short-range-chart.png
-GNUstep/Local/Applications/oolite.app/Resources/Images/solar.png
-GNUstep/Local/Applications/oolite.app/Resources/Images/splash.bmp
-GNUstep/Local/Applications/oolite.app/Resources/Images/splash.png
-GNUstep/Local/Applications/oolite.app/Resources/Images/trumblebox.png
-GNUstep/Local/Applications/oolite.app/Resources/Info-gnustep.plist
-GNUstep/Local/Applications/oolite.app/Resources/InfoPlist.strings
-GNUstep/Local/Applications/oolite.app/Resources/Models/adder_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/alloy.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/anaconda_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/arcdetail.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/asp_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/asteroid.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/asteroid1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/barrel.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/boa2_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/boa_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/boulder.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/boulder1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/buoy.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra1_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra1_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra1_redux2.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra3_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/cobra3_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/constrictor_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/dock-flat.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/dock.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/escpod_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/ferdelance_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/gecko_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/krait_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/mamba_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/mamba_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/missile.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/moray_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/moray_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/new-dodo.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/new-icos.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/new-rock.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/new_coriolis.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/oolite-ball-turret.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/oolite-unknown-ship.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/python_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/python_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/python_redux2.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/qbomb.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/ring.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/rock-box.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/rock-dock.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/scarred_alloy.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/shuttle_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/sidewinder_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/splinter.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/splinter1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/strut.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/thargoid_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/thargon_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/transporter_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/transporter_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/viper_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/viperi_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/worm_redux.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/worm_redux1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck1.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck2.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck3.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck4.dat
-GNUstep/Local/Applications/oolite.app/Resources/Models/wreck5.dat
-GNUstep/Local/Applications/oolite.app/Resources/Music/BlueDanube.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Music/OoliteTheme.ogg
-GNUstep/Local/Applications/oolite.app/Resources/README.TXT
-GNUstep/Local/Applications/oolite.app/Resources/Schemata/README.txt
-GNUstep/Local/Applications/oolite.app/Resources/Schemata/demoshipsSchema.plist
-GNUstep/Local/Applications/oolite.app/Resources/Schemata/hudSchema.plist
-GNUstep/Local/Applications/oolite.app/Resources/Schemata/plistschema.plist
-GNUstep/Local/Applications/oolite.app/Resources/Schemata/shipdataEntrySchema.plist
-GNUstep/Local/Applications/oolite.app/Resources/Schemata/shipyardSchema.plist
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-cloaking-device-mission.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-cloaking-device-pod.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-cloaking-device-target-ship.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-constrictor-hunt-mission.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-constrictor-pilot.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-constrictor.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-default-player-script.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-default-ship-script.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-global-prefix.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-locale-functions.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-nova-mission.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-thargoid-plans-mission.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-thargoid-warship.js
-GNUstep/Local/Applications/oolite.app/Resources/Scripts/oolite-trumbles-mission.js
-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-default-shader.fragment
-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-dust.fragment
-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-dust.vertex
-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-standard-vertex.vertex
-GNUstep/Local/Applications/oolite.app/Resources/Shaders/oolite-tangent-space-vertex.vertex
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/afterburner1.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/beep.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/bigbang.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/boop.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/breakpattern.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/buy.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/ecm.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/guiclick.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/hit.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/hullbang.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/laser.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/laserhits.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/missile.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/scoop.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/sell.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/trumble.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/trumblesqueal.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/warning.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Sounds/witchabort.ogg
-GNUstep/Local/Applications/oolite.app/Resources/Textures/MorayMED_bottom.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/MorayMED_top.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/adder_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/anaconda_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/arcdetail.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/asp_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/asteroid.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/back_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/barrel_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_left.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_rear.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_right.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa2_top.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/boa_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/bottom_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1_redux2.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra1miner_top.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra3_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/cobra3_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/constrictor_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/dark_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/ferdelance_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/front_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/galaxy256.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/gecko_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/krait_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/left_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/mamba_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/mamba_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/missile.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/moray_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/moray_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-ball-turret.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-barrel-specular.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-document.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-expansion-document.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-font.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-logo1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-2.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-3.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-nebula-4.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-particle-blur.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-particle-flash.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-scarred-metal-specular.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/oolite-star-1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/pod2_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/python_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/python_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/python_redux2.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/qbomb.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/right_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/scarred_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/shuttle_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/sidewinder_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/star64.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/target_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/thargoid_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/thargon_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/top_metal.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/transporter_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/transporter_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/trumblekit.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/viper_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/viperi_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/worm_redux.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/worm_redux1.png
-GNUstep/Local/Applications/oolite.app/Resources/Textures/wreck.png
-GNUstep/Local/Applications/oolite.app/Resources/oolite-document.icns
-GNUstep/Local/Applications/oolite.app/Resources/oolite-expansion-document.icns
-GNUstep/Local/Applications/oolite.app/Resources/oolite-icon.icns
-GNUstep/Local/Applications/oolite.app/oolite
-share/applications/oolite.desktop
-share/pixmaps/oolite-icon.png
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Textures
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Sounds
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Shaders
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Scripts
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Schemata
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Music
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Models
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Images
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/Config
-@dirrm GNUstep/Local/Applications/oolite.app/Resources/AIs
-@dirrm GNUstep/Local/Applications/oolite.app/Resources
-@dirrm GNUstep/Local/Applications/oolite.app