diff --git a/CGSConnection.h b/CGSConnection.h
index a479b5c..b4092ad 100644
--- a/CGSConnection.h
+++ b/CGSConnection.h
@@ -1,14 +1,14 @@
 /*
  * Copyright (C) 2007-2008 Alacatia Labs
- * 
+ *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the authors be held liable for any damages
  * arising from the use of this software.
- * 
+ *
  * Permission is granted to anyone to use this software for any purpose,
  * including commercial applications, and to alter it and redistribute it
  * freely, subject to the following restrictions:
- * 
+ *
  * 1. The origin of this software must not be misrepresented; you must not
  *    claim that you wrote the original software. If you use this software
  *    in a product, an acknowledgment in the product documentation would be
@@ -16,7 +16,7 @@
  * 2. Altered source versions must be plainly marked as such, and must not be
  *    misrepresented as being the original software.
  * 3. This notice may not be removed or altered from any source distribution.
- * 
+ *
  * Joe Ranieri joe@alacatia.com
  *
  */
@@ -230,7 +230,7 @@ CG_EXTERN CGError CGSSetLoginwindowConnection(CGSConnectionID cid) AVAILABLE_MAC
 
 //! The data sent with kCGSNotificationAppUnresponsive and kCGSNotificationAppResponsive.
 typedef struct {
-#if __BIG_ENDIAN__
+#ifdef __BIG_ENDIAN__
 	uint16_t majorVersion;
 	uint16_t minorVersion;
 #else
diff --git a/Makefile b/Makefile
index bc3972f..7b4a857 100644
--- a/Makefile
+++ b/Makefile
@@ -1,70 +1,156 @@
 mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
 current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
 
-MODULE := $(current_dir)
+# Universal build info mostly from
+#     https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary
+# Insight on Universal dSYM from
+#     https://lists.apple.com/archives/xcode-users/2009/Apr/msg00034.html
+
+MODULE := $(lastword $(subst ., ,$(current_dir)))
 PREFIX ?= ~/.hammerspoon
+MODPATH = hs/_asm/undocumented
+VERSION ?= 0.x
 HS_APPLICATION ?= /Applications
 
-OBJCFILE = ${wildcard *.m}
-LUAFILE  = ${wildcard *.lua}
-HEADERS  = ${wildcard *.h}
+# get from https://github.com/asmagill/hammerspoon-config/blob/master/utils/docmaker.lua
+# if you want to generate a readme file similar to the ones I generally use. Adjust the copyright in the file and adjust
+# this variable to match where you save docmaker.lua relative to your hammerspoon configuration directory
+# (usually ~/.hammerspoon)
+MARKDOWNMAKER = utils/docmaker.lua
+
+OBJCFILES = ${wildcard *.m}
+LUAFILES  = ${wildcard *.lua}
+HEADERS   = ${wildcard *.h}
+
+# for compiling each source file into a separate library
+#     (see also obj_x86_64/%.s and obj_arm64/%.s below)
+SOFILES  := $(OBJCFILES:.m=.so)
+
+# for compiling all source files into one library
+#     (see also obj_x86_64/%.s and obj_arm64/%.s below)
+# SOFILES  := internal.so
+
+SOFILES_x86_64   := $(addprefix obj_x86_64/,$(SOFILES))
+SOFILES_arm64    := $(addprefix obj_arm64/,$(SOFILES))
+SOFILES_univeral := $(addprefix obj_universal/,$(SOFILES))
 
-SOFILE  := $(OBJCFILE:.m=.so)
 DEBUG_CFLAGS ?= -g
-DOC_FILE = hs._asm.undocumented.$(MODULE).json
 
 # special vars for uninstall
 space :=
 space +=
 comma := ,
-ALLFILES := $(LUAFILE)
-ALLFILES += $(SOFILE)
+ALLFILES := $(LUAFILES)
+ALLFILES += $(SOFILES)
+
+# CC=clang
+CC=@clang
+WARNINGS ?= -Weverything -Wno-objc-missing-property-synthesis -Wno-implicit-atomic-properties -Wno-direct-ivar-access -Wno-cstring-format-directive -Wno-padded -Wno-covered-switch-default -Wno-missing-prototypes -Werror-implicit-function-declaration -Wno-documentation-unknown-command -Wno-poison-system-directories
+EXTRA_CFLAGS ?= -F$(HS_APPLICATION)/Hammerspoon.app/Contents/Frameworks -DSOURCE_PATH="$(mkfile_path)"
+MIN_intel_VERSION ?= -mmacosx-version-min=10.13
+MIN_arm64_VERSION ?= -mmacosx-version-min=11
+
+CFLAGS  += $(DEBUG_CFLAGS) -fmodules -fobjc-arc -DHS_EXTERNAL_MODULE $(WARNINGS) $(EXTRA_CFLAGS)
+release: CFLAGS  += -DRELEASE_VERSION=$(VERSION)
+releaseWithDocs: CFLAGS  += -DRELEASE_VERSION=$(VERSION)
+LDFLAGS += -dynamiclib -undefined dynamic_lookup $(EXTRA_LDFLAGS)
 
-.SUFFIXES: .m .so
+all: verify $(shell uname -m)
 
-#CC=cc
-CC=clang
-EXTRA_CFLAGS ?= -Wconversion -Wdeprecated -F$(HS_APPLICATION)/Hammerspoon.app/Contents/Frameworks
-CFLAGS  += $(DEBUG_CFLAGS) -fobjc-arc -DHS_EXTERNAL_MODULE -Wall -Wextra $(EXTRA_CFLAGS)
-LDFLAGS += -dynamiclib -undefined dynamic_lookup $(EXTRA_LDFLAGS)
+x86_64: $(SOFILES_x86_64)
 
-DOC_SOURCES = $(LUAFILE) $(OBJCFILE)
+arm64: $(SOFILES_arm64)
 
-all: verify $(SOFILE)
+universal: verify x86_64 arm64 $(SOFILES_univeral)
 
-.m.so: $(HEADERS)
-	$(CC) $< $(CFLAGS) $(LDFLAGS) -o $@
+# for compiling each source file into a separate library
+#     (see also SOFILES above)
 
-install: verify install-objc install-lua
+obj_x86_64/%.so: %.m $(HEADERS)
+	$(CC) $< $(CFLAGS) $(MIN_intel_VERSION) $(LDFLAGS) -target x86_64-apple-macos10.13 -o $@
 
-verify: $(LUAFILE)
-	luac-5.3 -p $(LUAFILE) && echo "Passed"
+obj_arm64/%.so: %.m $(HEADERS)
+	$(CC) $< $(CFLAGS) $(MIN_arm64_VERSION) $(LDFLAGS) -target arm64-apple-macos11 -o $@
 
-install-objc: $(SOFILE)
-	mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE)
-	install -m 0644 $(SOFILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE)
-	cp -vpR $(OBJCFILE:.m=.so.dSYM) $(PREFIX)/hs/_asm/undocumented/$(MODULE)
+# for compiling all source files into one library
+#     (see also SOFILES above)
 
-install-lua: $(LUAFILE)
-	mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE)
-	install -m 0644 $(LUAFILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE)
+# obj_x86_64/%.so: $(OBJCFILES) $(HEADERS)
+# 	$(CC) $(OBJCFILES) $(CFLAGS) $(MIN_intel_VERSION) $(LDFLAGS) -target x86_64-apple-macos10.13 -o $@
+#
+# obj_arm64/%.so: $(OBJCFILES) $(HEADERS)
+# 	$(CC) $(OBJCFILES) $(CFLAGS) $(MIN_arm64_VERSION) $(LDFLAGS) -target arm64-apple-macos11 -o $@
 
-docs: $(DOC_FILE)
+# creating the universal dSYM bundle is a total hack because I haven't found a better
+# way yet... suggestions welcome
+obj_universal/%.so: $(SOFILES_x86_64) $(SOFILES_arm64)
+	lipo -create -output $@ $(subst universal/,x86_64/,$@) $(subst universal/,arm64/,$@)
+	mkdir -p $@.dSYM/Contents/Resources/DWARF/
+	cp $(subst universal/,x86_64/,$@).dSYM/Contents/Info.plist $@.dSYM/Contents
+	lipo -create -output $@.dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) $(subst universal/,x86_64/,$@).dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) $(subst universal/,arm64/,$@).dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@)
 
-$(DOC_FILE): $(DOC_SOURCES)
-	find . -type f \( -name '*.lua' -o -name '*.m' \) -not -name 'template.*' -not -path './_*' -exec cat {} + | __doc_tools/gencomments | __doc_tools/genjson > $@
+$(SOFILES_x86_64): | obj_x86_64
 
-install-docs: docs
-	mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE)
-	install -m 0644 $(DOC_FILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE)
+$(SOFILES_arm64): | obj_arm64
 
-clean:
-	rm -v -rf $(SOFILE) *.dSYM $(DOC_FILE)
+$(SOFILES_univeral): | obj_universal
+
+obj_x86_64:
+	mkdir obj_x86_64
+
+obj_arm64:
+	mkdir obj_arm64
+
+obj_universal:
+	mkdir obj_universal
+
+verify: $(LUAFILES)
+	@if $$(hash lua >& /dev/null); then (luac -p $(LUAFILES) && echo "Lua Compile Verification Passed"); else echo "Skipping Lua Compile Verification"; fi
+
+install: install-$(shell uname -m)
+
+install-lua: $(LUAFILES)
+	mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE)
+	install -m 0644 $(LUAFILES) $(PREFIX)/$(MODPATH)/$(MODULE)
+	test -f docs.json && install -m 0644 docs.json $(PREFIX)/$(MODPATH)/$(MODULE) || echo "No docs.json file to install"
+
+install-x86_64: verify install-lua $(SOFILES_x86_64)
+	mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE)
+	install -m 0644 $(SOFILES_x86_64) $(PREFIX)/$(MODPATH)/$(MODULE)
+	cp -vpR $(SOFILES_x86_64:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE)
+
+install-arm64: verify install-lua $(SOFILES_arm64)
+	mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE)
+	install -m 0644 $(SOFILES_arm64) $(PREFIX)/$(MODPATH)/$(MODULE)
+	cp -vpR $(SOFILES_arm64:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE)
+
+install-universal: verify install-lua $(SOFILES_univeral)
+	mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE)
+	install -m 0644 $(SOFILES_univeral) $(PREFIX)/$(MODPATH)/$(MODULE)
+	cp -vpR $(SOFILES_univeral:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE)
 
 uninstall:
-	rm -v -f $(PREFIX)/hs/_asm/undocumented/$(MODULE)/{$(subst $(space),$(comma),$(ALLFILES))}
-	(pushd $(PREFIX)/hs/_asm/undocumented/$(MODULE)/ ; rm -v -fr $(OBJCFILE:.m=.so.dSYM) ; popd)
-	rm -v -f $(PREFIX)/hs/_asm/undocumented/$(MODULE)/$(DOC_FILE)
-	rmdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) ; exit 0
+	rm -v -f $(PREFIX)/$(MODPATH)/$(MODULE)/{$(subst $(space),$(comma),$(ALLFILES))}
+	(pushd $(PREFIX)/$(MODPATH)/$(MODULE)/ ; rm -v -fr $(SOFILES:.so=.so.dSYM) ; popd)
+	rm -v -f $(PREFIX)/$(MODPATH)/$(MODULE)/docs.json
+	rmdir -p $(PREFIX)/$(MODPATH)/$(MODULE) ; exit 0
+
+clean:
+	rm -rf obj_x86_64 obj_arm64 obj_universal tmp docs.json
+
+docs:
+	hs -c "require(\"hs.doc\").builder.genJSON(\"$(dir $(mkfile_path))\")" > docs.json
+
+markdown:
+	hs -c "dofile(\"$(MARKDOWNMAKER)\").genMarkdown([[$(dir $(mkfile_path))]])" > README.tmp.md
+
+markdownWithTOC:
+	hs -c "dofile(\"$(MARKDOWNMAKER)\").genMarkdown([[$(dir $(mkfile_path))]], true)" > README.tmp.md
+
+release: clean all
+	HS_APPLICATION=$(HS_APPLICATION) PREFIX=tmp make install-universal ; cd tmp ; tar -cf ../$(MODULE)-v$(VERSION).tar hs ; cd .. ; gzip $(MODULE)-v$(VERSION).tar
+
+releaseWithDocs: clean all docs
+	HS_APPLICATION=$(HS_APPLICATION) PREFIX=tmp make install-universal ; cd tmp ; tar -cf ../$(MODULE)-v$(VERSION).tar hs ; cd .. ; gzip $(MODULE)-v$(VERSION).tar
 
-.PHONY: all clean uninstall verify docs install install-objc install-lua install-docs
+.PHONY: all clean verify install install-lua install-x86_64 install-arm64 install-universal docs markdown markdownWithTOC release releaseWithDocs
diff --git a/README.md b/README.md
index c7c5548..a8c0459 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,14 @@
 _asm.undocumented.spaces
 ========================
 
+** This module has been superseded by https://github.com/asmagill/hs._asm.spaces and is no longer being maintained. **
+
+It is being kept around for historical purposes, but is considered woefully out of date, buggy, likely broken and potentially dangerous to your health and/or sanity.
+
+If you find that the newer module still does not meet your requirements, then I suggest looking into https://github.com/koekeishiya/yabai which (at the time of this posting) is actively maintained and provides a lot more flexibility and functionality. A bridging Spoon between Yabai and Hammerspoon is being considered, but there is no ETA and you are encouraged to write one yourself if desired -- there are certainly Hammerspoon users who would be interested.
+
+- - -
+
 This module provides Hammerspoon with access to the undocumented Spaces API.  For backwards compatibility, it replicates the original legacy functions from the Hammerspoon precursors, [Hydra and Mjolnir](https://www.github.com/sdegutis)'s module of the same name, but also provides more direct access to the available functions.
 
 Most of the Spaces API detail in this module comes from [NUIKit/CGSInternal](https://github.com/NUIKit/CGSInternal) with a few changes made to include some functions found in previous incarnations of this module and other Google searches.
@@ -9,6 +17,8 @@ I make no promises that these will work for you or work at all with any, past, c
 
 ### Installation
 
+*See https://github.com/asmagill/hammerspoon_asm/blob/master/README.md for details about building this module as a Universal library*
+
 Compiled versions of this module can be found in the releases.  You can download the release and install it by expanding it in your `~/.hammerspoon/` directory (or any other directory in your `package.path` and `package.cpath` search paths):
 
 ~~~sh
diff --git a/init.lua b/init.lua
index 17b3ddf..ea1d14e 100644
--- a/init.lua
+++ b/init.lua
@@ -3,10 +3,21 @@
 --- These functions utilize private API's within the OS X internals, and are known to have unpredictable behavior under Mavericks and Yosemite when "Displays have separate Spaces" is checked under the Mission Control system preferences.
 ---
 
+local USERDATA_TAG = "hs._asm.undocumented.spaces"
 -- some of the commands can really get you in a bit of a fix, so this file will be mostly wrappers and
 -- predefined, common actions.
-local internal = require("hs._asm.undocumented.spaces.internal")
-local module = {}
+local internal = require(USERDATA_TAG..".internal")
+local module   = {}
+
+local basePath = package.searchpath(USERDATA_TAG, package.path)
+if basePath then
+    basePath = basePath:match("^(.+)/init.lua$")
+    if require"hs.fs".attributes(basePath .. "/docs.json") then
+        require"hs.doc".registerJSONFile(basePath .. "/docs.json")
+    end
+end
+
+-- local log = require("hs.logger").new(USERDATA_TAG, require"hs.settings".get(USERDATA_TAG .. ".logLevel") or "warning")
 
 local screen      = require("hs.screen")
 local window      = require("hs.window")
@@ -292,7 +303,7 @@ module.removeSpace = function(...)
         _BE_DANGEROUS_FLAG_ = _Are_We_Being_Dangerous_
         -- check for windows which need to be moved
         local theWindows = {}
-        for i, v in ipairs(module.allWindowsForSpace(spaceID)) do table.insert(theWindows, v:id()) end
+        for i, v in ipairs(module.allWindowsForSpace(spaceID)) do if v:id() then table.insert(theWindows, v:id()) end end
 
         -- get id of screen to move them to
         local baseID = 0
@@ -368,9 +379,11 @@ module.allWindowsForSpace = function(...)
         end
         local realWindowIDs = {}
         for i,v in ipairs(windowIDs) do
-            for j,k in ipairs(internal.windowsOnSpaces(v:id())) do
-                if k == spaceID then
-                    table.insert(realWindowIDs, v)
+            if v:id() then
+                for j,k in ipairs(internal.windowsOnSpaces(v:id())) do
+                    if k == spaceID then
+                        table.insert(realWindowIDs, v)
+                    end
                 end
             end
         end
@@ -402,9 +415,10 @@ module.moveWindowToSpace = function(...)
         elseif #currentSpaces > 1 then
             error("moveWindowToSpace:window on multiple spaces", 2)
         end
-
-        internal.windowsAddTo(windowID, spaceID)
-        internal.windowsRemoveFrom(windowID, currentSpaces[1])
+        if currentSpaces[1] ~= spaceID then
+            internal.windowsAddTo(windowID, spaceID)
+            internal.windowsRemoveFrom(windowID, currentSpaces[1])
+        end
         return internal.windowsOnSpaces(windowID)[1]
     else
         error("moveWindowToSpace:invalid argument, windowID and spaceID expected", 2)
@@ -414,9 +428,13 @@ end
 module.layout = function()
     local results = {}
     for i,v in ipairs(internal.details()) do
-        results[v["Display Identifier"]] = {}
+        local screenID = v["Display Identifier"]
+        if screenID == "Main" then
+            screenID = module.mainScreenUUID()
+        end
+        results[screenID] = {}
         for j,k in ipairs(v.Spaces) do
-            table.insert(results[v["Display Identifier"]], k.ManagedSpaceID)
+            table.insert(results[screenID], k.ManagedSpaceID)
         end
     end
     return results
@@ -518,10 +536,13 @@ screenMT.__index.spaces          = function(obj) return module.spacesByScreenUUI
 screenMT.__index.spacesUUID      = internal.UUIDforScreen
 screenMT.__index.spacesAnimating = function(obj) return internal.screenUUIDisAnimating(internal.UUIDforScreen(obj)) end
 
-windowMT.__index.spaces          = function(obj) return internal.windowsOnSpaces(obj:id()) end
+windowMT.__index.spaces          = function(obj) return obj:id() and internal.windowsOnSpaces(obj:id()) or nil end
 windowMT.__index.spacesMoveTo    = function(obj, ...)
-    module.moveWindowToSpace(obj:id(), ...)
-    return obj
+    if obj:id() then
+        module.moveWindowToSpace(obj:id(), ...)
+        return obj
+    end
+    return nil
 end
 
 -- add raw subtable if the user has enabled it
diff --git a/internal.m b/internal.m
index e82feb7..3134120 100644
--- a/internal.m
+++ b/internal.m
@@ -1,27 +1,28 @@
-#import <Cocoa/Cocoa.h>
-// #import <Carbon/Carbon.h>
-#import <LuaSkin/LuaSkin.h>
-// #import "spaces.h"
+@import Cocoa ;
+@import LuaSkin ;
 #import "CGSSpace.h"
 
 extern CGSConnectionID _CGSDefaultConnection(void);
 #define CGSDefaultConnection _CGSDefaultConnection()
 
-int refTable ;
+static LSRefTable refTable ;
 
 #pragma mark - Support Functions
 
 BOOL isScreenUUIDValid(NSString *theDisplay) {
     BOOL isValid = NO ;
     for (NSScreen *screen in [NSScreen screens]) {
-        CGDirectDisplayID cgID = [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue] ;
+        NSNumber *screenNumber = [[screen deviceDescription] objectForKey:@"NSScreenNumber"] ;
+        CGDirectDisplayID cgID = screenNumber.unsignedIntValue ;
         CFUUIDRef   theUUID    = CGDisplayCreateUUIDFromDisplayID(cgID) ;
-        CFStringRef UUIDString = CFUUIDCreateString(kCFAllocatorDefault, theUUID) ;
-        if (CFStringCompare((__bridge CFStringRef)theDisplay, UUIDString, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
-            isValid = YES ;
-        CFRelease(UUIDString) ;
-        CFRelease(theUUID) ;
-        if (isValid) break ;
+        if (theUUID) {
+            CFStringRef UUIDString = CFUUIDCreateString(kCFAllocatorDefault, theUUID) ;
+            if (CFStringCompare((__bridge CFStringRef)theDisplay, UUIDString, kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+                isValid = YES ;
+            CFRelease(UUIDString) ;
+            CFRelease(theUUID) ;
+            if (isValid) break ;
+        }
     }
     return isValid ;
 }
@@ -83,7 +84,8 @@ static int CGSRegionRefToLua(lua_State *L, CGSRegionRef theRegion) {
 #pragma mark - Module Functions
 
 static int changeToSpace(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
 // Moved to lua for more flexibility
 //     CGSHideSpaces(CGSDefaultConnection, (__bridge CFArrayRef)(@[@(CGSGetActiveSpace(CGSDefaultConnection))]));
 //     CGSShowSpaces(CGSDefaultConnection, (__bridge CFArrayRef)(@[@(luaL_checkinteger(L, 1))]));
@@ -93,15 +95,23 @@ static int changeToSpace(lua_State *L) {
     return 0 ;
 }
 
-static int disableUpdates(__unused lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TBREAK] ;
+static int disableUpdates(lua_State *L) {
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TBREAK] ;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
     NSDisableScreenUpdates() ;
+#pragma clang diagnostic pop
     return 0 ;
 }
 
-static int enableUpdates(__unused lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TBREAK] ;
+static int enableUpdates(lua_State *L) {
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TBREAK] ;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
     NSEnableScreenUpdates() ;
+#pragma clang diagnostic pop
     return 0 ;
 }
 
@@ -118,45 +128,57 @@ static int enableUpdates(__unused lua_State *L) {
 /// Notes:
 ///  * This function uses standard OS X APIs and is not likely to be affected by updates or patches.
 static int screensHaveSeparateSpaces(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TBREAK] ;
     lua_pushboolean(L, [NSScreen screensHaveSeparateSpaces]) ;
     return 1 ;
 }
 
 static int screenUUID(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TUSERDATA, "hs.screen", LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TUSERDATA, "hs.screen", LS_TBREAK] ;
     NSScreen *screen = (__bridge NSScreen*)*((void**)luaL_checkudata(L, 1, "hs.screen")) ;
-    CGDirectDisplayID cgID = [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue] ;
+    NSNumber *screenNumber = [[screen deviceDescription] objectForKey:@"NSScreenNumber"] ;
+    CGDirectDisplayID cgID = screenNumber.unsignedIntValue ;
     CFUUIDRef   theUUID    = CGDisplayCreateUUIDFromDisplayID(cgID) ;
-    CFStringRef UUIDString = CFUUIDCreateString(kCFAllocatorDefault, theUUID) ;
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSString *)UUIDString] ;
+    if (theUUID) {
+        CFStringRef UUIDString = CFUUIDCreateString(kCFAllocatorDefault, theUUID) ;
+        [skin pushNSObject:(__bridge_transfer NSString *)UUIDString] ;
+        CFRelease(theUUID) ;
+    } else {
+        lua_pushnil(L) ;
+    }
     return 1 ;
 }
 
 static int spaceOwners(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CFArrayRef CGspaceOwners = CGSSpaceCopyOwners(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1));
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSArray *)CGspaceOwners] ;
+    [skin pushNSObject:(__bridge_transfer NSArray *)CGspaceOwners] ;
     return 1 ;
 }
 
 static int spaceType(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     lua_pushinteger(L, CGSSpaceGetType(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1))) ;
     return 1 ;
 }
 
 static int spaceName(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CFStringRef CGname = CGSSpaceCopyName(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1));
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSString *)CGname] ;
+    [skin pushNSObject:(__bridge_transfer NSString *)CGname] ;
     return 1 ;
 }
 
 static int spaceValues(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CFDictionaryRef CGspaceValues = CGSSpaceCopyValues(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1));
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSDictionary *)CGspaceValues] ;
+    [skin pushNSObject:(__bridge_transfer NSDictionary *)CGspaceValues] ;
     return 1 ;
 }
 
@@ -188,35 +210,40 @@ static int spacesTypesTable(lua_State *L) {
 }
 
 static int activeSpace(lua_State* L) {
-    [[LuaSkin shared] checkArgs:LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TBREAK] ;
     lua_pushinteger(L, (lua_Integer)CGSGetActiveSpace(CGSDefaultConnection)) ;
     return 1 ;
 }
 
 static int querySpaces(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
-    CFArrayRef CGspaces = CGSCopySpaces(CGSDefaultConnection, (CGSSpaceMask)lua_tointeger(L, 1));
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSArray *)CGspaces] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    CFArrayRef CGspaces = CGSCopySpaces(CGSDefaultConnection, (CGSSpaceMask)(lua_tointeger(L, 1)));
+    [skin pushNSObject:(__bridge_transfer NSArray *)CGspaces] ;
     return 1 ;
 }
 
-static int fullDetails(__unused lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TBREAK] ;
+static int fullDetails(lua_State *L) {
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TBREAK] ;
     CFArrayRef CGmanagedDisplaySpaces = CGSCopyManagedDisplaySpaces(CGSDefaultConnection);
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSArray *)CGmanagedDisplaySpaces] ;
+    [skin pushNSObject:(__bridge_transfer NSArray *)CGmanagedDisplaySpaces] ;
     return 1 ;
 }
 
 static int spaceScreenUUID(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CFStringRef display = CGSCopyManagedDisplayForSpace(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1));
-    [[LuaSkin shared] pushNSObject:(__bridge_transfer NSArray *)display] ;
+    [skin pushNSObject:(__bridge_transfer NSArray *)display] ;
     return 1 ;
 }
 
 static int screenUUIDisAnimating(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TSTRING, LS_TBREAK] ;
-    NSString *theDisplay = [[LuaSkin shared] toNSObjectAtIndex:1] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TSTRING, LS_TBREAK] ;
+    NSString *theDisplay = [skin toNSObjectAtIndex:1] ;
     BOOL isValid = isScreenUUIDValid(theDisplay) ;
 
     if (isValid)
@@ -227,8 +254,9 @@ static int screenUUIDisAnimating(lua_State *L) {
 }
 
 static int setScreenUUIDisAnimating(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TSTRING, LS_TBOOLEAN, LS_TBREAK] ;
-    NSString *theDisplay = [[LuaSkin shared] toNSObjectAtIndex:1] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TSTRING, LS_TBOOLEAN, LS_TBREAK] ;
+    NSString *theDisplay = [skin toNSObjectAtIndex:1] ;
     BOOL isValid = isScreenUUIDValid(theDisplay) ;
 
     if (isValid) {
@@ -241,14 +269,16 @@ static int setScreenUUIDisAnimating(lua_State *L) {
     return 1 ;
 }
 
-static int mainScreenUUID(__unused lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TBREAK] ;
-    [[LuaSkin shared] pushNSObject:(__bridge NSString *) kCGSPackagesMainDisplayIdentifier] ;
+static int mainScreenUUID(lua_State *L) {
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TBREAK] ;
+    [skin pushNSObject:(__bridge NSString *) kCGSPackagesMainDisplayIdentifier] ;
     return 1 ;
 }
 
 static int spaceLevel(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ;
 
     if (lua_type(L, 2) != LUA_TNONE) {
         CGSSpaceSetAbsoluteLevel(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1), (int)lua_tointeger(L, 2)) ;
@@ -259,15 +289,15 @@ static int spaceLevel(lua_State *L) {
 }
 
 static int spaceCompatID(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     lua_pushinteger(L, CGSSpaceGetCompatID(CGSDefaultConnection, (CGSSpaceID)lua_tointeger(L, 1))) ;
     return 1 ;
 }
 
 static int spaceTransform(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER,
-                                LS_TTABLE | LS_TNIL | LS_TOPTIONAL,
-                                LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TTABLE | LS_TNIL | LS_TOPTIONAL, LS_TBREAK] ;
 
     if (lua_type(L, 2) != LUA_TNONE) {
         CGAffineTransform trans = CGAffineTransformMakeScale(1, 1) ;
@@ -296,23 +326,26 @@ static int spaceTransform(lua_State *L) {
 }
 
 static int showSpaces(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
     NSArray *theSpaces = getArrayFromNumberOrArray(L, 1) ;
     CGSShowSpaces(CGSDefaultConnection, (__bridge CFArrayRef)theSpaces) ;
     return 0 ;
 }
 
 static int hideSpaces(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
     NSArray *theSpaces = getArrayFromNumberOrArray(L, 1) ;
     CGSHideSpaces(CGSDefaultConnection, (__bridge CFArrayRef)theSpaces) ;
     return 0 ;
 }
 
 static int createSpace(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TSTRING, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TSTRING, LS_TBREAK] ;
     NSDictionary *stuff = @{@"type":@(kCGSSpaceUser), @"uuid":[[NSUUID UUID] UUIDString]} ;
-    NSString *theDisplay = [[LuaSkin shared] toNSObjectAtIndex:1] ;
+    NSString *theDisplay = [skin toNSObjectAtIndex:1] ;
     BOOL isValid = isScreenUUIDValid(theDisplay) ;
 
     if (isValid) {
@@ -327,13 +360,15 @@ static int createSpace(lua_State *L) {
 }
 
 static int removeSpace(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CGSSpaceDestroy(CGSDefaultConnection, (CGSSpaceID)luaL_checkinteger(L, 1)) ;
     return 0 ;
 }
 
 static int windowsAddTo(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER | LS_TTABLE, LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER | LS_TTABLE, LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
     NSArray *theWindows = getArrayFromNumberOrArray(L, 1) ;
     NSArray *theSpaces  = getArrayFromNumberOrArray(L, 2) ;
     CGSAddWindowsToSpaces(CGSDefaultConnection, (__bridge CFArrayRef)theWindows, (__bridge CFArrayRef)theSpaces);
@@ -341,7 +376,8 @@ static int windowsAddTo(lua_State *L) {
 }
 
 static int windowsRemoveFrom(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER | LS_TTABLE, LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER | LS_TTABLE, LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
     NSArray *theWindows = getArrayFromNumberOrArray(L, 1) ;
     NSArray *theSpaces  = getArrayFromNumberOrArray(L, 2) ;
     CGSRemoveWindowsFromSpaces(CGSDefaultConnection, (__bridge CFArrayRef)theWindows, (__bridge CFArrayRef)theSpaces);
@@ -349,15 +385,17 @@ static int windowsRemoveFrom(lua_State *L) {
 }
 
 static int windowsOnSpaces(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER | LS_TTABLE, LS_TBREAK] ;
     NSArray *theWindows = getArrayFromNumberOrArray(L, 1) ;
     NSArray *results = (__bridge_transfer NSArray *)CGSCopySpacesForWindows(CGSDefaultConnection, kCGSAllSpacesMask, (__bridge CFArrayRef)theWindows) ;
-    [[LuaSkin shared] pushNSObject:results] ;
+    [skin pushNSObject:results] ;
     return 1 ;
 }
 
 static int spaceShape(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CGSRegionRef theRegion = CGSSpaceCopyShape(CGSDefaultConnection, (CGSSpaceID)luaL_checkinteger(L, 1)) ;
     CGSRegionRefToLua(L, theRegion) ;
     if (theRegion) CGSReleaseRegion(theRegion) ;
@@ -365,7 +403,8 @@ static int spaceShape(lua_State *L) {
 }
 
 static int spaceManagedShape(lua_State *L) {
-    [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ;
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    [skin checkArgs:LS_TNUMBER, LS_TBREAK] ;
     CGSRegionRef theRegion = CGSSpaceCopyManagedShape(CGSDefaultConnection, (CGSSpaceID)luaL_checkinteger(L, 1)) ;
     CGSRegionRefToLua(L, theRegion) ;
     if (theRegion) CGSReleaseRegion(theRegion) ;
@@ -415,8 +454,9 @@ static int spaceManagedShape(lua_State *L) {
     {NULL, NULL},
 };
 
-int luaopen_hs__asm_undocumented_spaces_internal(__unused lua_State* L) {
-    refTable = [[LuaSkin shared] registerLibrary:moduleLib metaFunctions:nil] ;
+int luaopen_hs__asm_undocumented_spaces_internal(lua_State* L) {
+    LuaSkin *skin = [LuaSkin sharedWithState:L] ;
+    refTable = [skin registerLibrary:"hs._asm.undocumented.spaces" functions:moduleLib metaFunctions:nil] ;
 
     spacesMasksTable(L) ; lua_setfield(L, -2, "masks") ;
     spacesTypesTable(L) ; lua_setfield(L, -2, "types") ;