diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt
index 5d61190286..ad01750aa1 100644
--- a/assignment-client/CMakeLists.txt
+++ b/assignment-client/CMakeLists.txt
@@ -25,9 +25,11 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
 link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR})
 link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
 link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
+link_hifi_library(voxel-server-library ${TARGET_NAME} ${ROOT_DIR})
 
 # link the stk library
 set(STK_ROOT_DIR ${ROOT_DIR}/externals/stk)
 find_package(STK REQUIRED)
 target_link_libraries(${TARGET_NAME} ${STK_LIBRARIES})
-include_directories(${STK_INCLUDE_DIRS})
\ No newline at end of file
+include_directories(${STK_INCLUDE_DIRS})
+
diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp
index 2ad8345e53..f58828e65f 100644
--- a/assignment-client/src/main.cpp
+++ b/assignment-client/src/main.cpp
@@ -22,6 +22,7 @@
 #include <NodeList.h>
 #include <PacketHeaders.h>
 #include <SharedUtil.h>
+#include <VoxelServer.h>
 
 const long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000;
 const char PARENT_TARGET_NAME[] = "assignment-client-monitor";
@@ -97,6 +98,8 @@ void childClient() {
                     AudioMixer::run();
                 } else if (deployedAssignment.getType() == Assignment::AvatarMixerType) {
                     AvatarMixer::run();
+                } else if (deployedAssignment.getType() == Assignment::VoxelServerType) {
+                    VoxelServer::run();
                 } else {
                     // figure out the URL for the script for this agent assignment
                     QString scriptURLString("http://%1:8080/assignment/%2");
diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt
index 1026f6c0b3..3c54a2d7f0 100644
--- a/domain-server/CMakeLists.txt
+++ b/domain-server/CMakeLists.txt
@@ -10,9 +10,9 @@ setup_hifi_project(${TARGET_NAME} TRUE)
 
 # setup a library for civetweb and link it to the domain-server
 FILE(GLOB CIVETWEB_SRCS external/civetweb/src/*.c)
-add_library(CIVETWEB ${CIVETWEB_SRCS})
+add_library(civetweb ${CIVETWEB_SRCS})
 include_directories(external/civetweb/include)
-target_link_libraries(${TARGET_NAME} CIVETWEB)
+target_link_libraries(${TARGET_NAME} civetweb)
 
 # remove and then copy the files for the webserver
 add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
@@ -25,4 +25,9 @@ add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
 
 # link the shared hifi library
 include(${MACRO_DIR}/LinkHifiLibrary.cmake)
-link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
\ No newline at end of file
+link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
+
+# link dl library on UNIX for civetweb
+if (UNIX AND NOT APPLE)
+  target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
+endif (UNIX AND NOT APPLE)
\ No newline at end of file
diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp
index b4b5c0ec36..3cb433b933 100644
--- a/domain-server/src/main.cpp
+++ b/domain-server/src/main.cpp
@@ -155,6 +155,10 @@ int main(int argc, const char* argv[]) {
     Assignment avatarMixerAssignment(Assignment::CreateCommand,
                                      Assignment::AvatarMixerType,
                                      Assignment::LocalLocation);
+
+    Assignment voxelServerAssignment(Assignment::CreateCommand,
+                                     Assignment::VoxelServerType,
+                                     Assignment::LocalLocation);
     
     // construct a local socket to send with our created assignments to the global AS
     sockaddr_in localSocket = {};
@@ -168,8 +172,6 @@ int main(int argc, const char* argv[]) {
     
     QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
     
-    qDebug() << documentRoot << "\n";
-    
     // list of options. Last element must be NULL.
     const char *options[] = {"listening_ports", "8080",
                              "document_root", documentRoot.toStdString().c_str(), NULL};
@@ -180,6 +182,9 @@ int main(int argc, const char* argv[]) {
     // Start the web server.
     ctx = mg_start(&callbacks, NULL, options);
     
+    // wait to check on voxel-servers till we've given our NodeList a chance to get a good list
+    int checkForVoxelServerAttempt = 0;
+    
     while (true) {
         
         ::assignmentQueueMutex.lock();
@@ -196,6 +201,27 @@ int main(int argc, const char* argv[]) {
             qDebug("Missing an audio mixer and assignment not in queue. Adding.\n");
             ::assignmentQueue.push_front(&audioMixerAssignment);
         }
+
+        // Now handle voxel servers. Couple of things are special about voxel servers. 
+        // 1) They can run standalone, and so we want to wait to ask for an assignment until we've given them sufficient
+        //    time to check in with us. So we will look for them, but we want actually add assignments unless we haven't 
+        //    seen one after a few tries.
+        // 2) They aren't soloNodeOfType() so we have to count them.
+        int voxelServerCount = 0;
+        for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
+            if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
+                voxelServerCount++;
+            }
+        }
+        const int MIN_VOXEL_SERVER_CHECKS = 10;
+        if (checkForVoxelServerAttempt > MIN_VOXEL_SERVER_CHECKS &&
+            voxelServerCount == 0 &&
+            std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &voxelServerAssignment) == ::assignmentQueue.end()) {
+            qDebug("Missing a Voxel Server and assignment not in queue. Adding.\n");
+            ::assignmentQueue.push_front(&voxelServerAssignment);
+        }
+        checkForVoxelServerAttempt++;
+
         ::assignmentQueueMutex.unlock();
         
         while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp
index 084b1f8c85..0df2f2d41c 100755
--- a/interface/src/avatar/Avatar.cpp
+++ b/interface/src/avatar/Avatar.cpp
@@ -723,7 +723,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
             //  Always render other people, and render myself when beyond threshold distance
             if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
                 if (alpha > 0.0f) {
-                    _head.render(alpha);
+                    _head.render(alpha, false);
                 }
             } else if (alpha > 0.0f) {
                 //  Render the body ball sphere
@@ -767,7 +767,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
         float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
         if (alpha > 0.0f) {
             _voxels.render(false);
-            _head.render(alpha);
+            _head.render(alpha, false);
         }
     }
     _hand.render(lookingInMirror);
diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp
index af6133460f..9c86f92e2b 100644
--- a/interface/src/avatar/Head.cpp
+++ b/interface/src/avatar/Head.cpp
@@ -322,7 +322,7 @@ void Head::calculateGeometry() {
                            + up    * _scale * NOSE_UPTURN;  
 }
 
-void Head::render(float alpha) {
+void Head::render(float alpha, bool isMine) {
     _renderAlpha = alpha;
 
     if (!_face.render(alpha)) {
@@ -331,7 +331,7 @@ void Head::render(float alpha) {
         glEnable(GL_DEPTH_TEST);
         glEnable(GL_RESCALE_NORMAL);
 
-        if (Menu::getInstance()->isOptionChecked(MenuOption::UsePerlinFace)) {
+        if (Menu::getInstance()->isOptionChecked(MenuOption::UsePerlinFace) && isMine) {
             _perlinFace.render();
         } else  {
             renderMohawk();
diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h
index 496fdecef6..90d4507c7b 100644
--- a/interface/src/avatar/Head.h
+++ b/interface/src/avatar/Head.h
@@ -43,7 +43,7 @@ public:
     void init();
     void reset();
     void simulate(float deltaTime, bool isMine, float gyroCameraSensitivity);
-    void render(float alpha);
+    void render(float alpha, bool isMine);
     void renderMohawk();
 
     void setScale(float scale);
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index 0dcfe32236..c9d0dd37bc 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -557,7 +557,7 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
             // Always render other people, and render myself when beyond threshold distance
             if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special
                 if (alpha > 0.0f) {
-                    _head.render(alpha);
+                    _head.render(alpha, true);
                 }
             } else if (alpha > 0.0f) {
                 // Render the body ball sphere
@@ -614,7 +614,7 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
         float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
         if (alpha > 0.0f) {
             _voxels.render(false);
-            _head.render(alpha);
+            _head.render(alpha, true);
         }
     }
     _hand.render(lookingInMirror);
diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp
index cc86785e60..e1480e39d2 100644
--- a/interface/src/devices/Faceshift.cpp
+++ b/interface/src/devices/Faceshift.cpp
@@ -28,6 +28,10 @@ Faceshift::Faceshift() :
     _rightBlink(0.0f),
     _leftEyeOpen(0.0f),
     _rightEyeOpen(0.0f),
+    _leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
+    _rightBlinkIndex(1),
+    _leftEyeOpenIndex(8),
+    _rightEyeOpenIndex(9),
     _browDownLeft(0.0f),
     _browDownRight(0.0f),
     _browUpCenter(0.0f),
@@ -35,6 +39,7 @@ Faceshift::Faceshift() :
     _browUpRight(0.0f),
     _browDownLeftIndex(-1),
     _browDownRightIndex(-1),
+    _browUpCenterIndex(16),
     _browUpLeftIndex(-1),
     _browUpRightIndex(-1),
     _mouthSize(0.0f),
@@ -42,11 +47,6 @@ Faceshift::Faceshift() :
     _mouthSmileRight(0),
     _mouthSmileLeftIndex(-1),
     _mouthSmileRightIndex(0),
-    _leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes
-    _rightBlinkIndex(1),
-    _leftEyeOpenIndex(8),
-    _rightEyeOpenIndex(9),
-    _browUpCenterIndex(16),
     _jawOpenIndex(21),
     _longTermAverageEyePitch(0.0f),
     _longTermAverageEyeYaw(0.0f),
diff --git a/libraries/shared/src/Assignment.h b/libraries/shared/src/Assignment.h
index dc246a9ad6..59e2c45db7 100644
--- a/libraries/shared/src/Assignment.h
+++ b/libraries/shared/src/Assignment.h
@@ -23,6 +23,7 @@ public:
         AudioMixerType,
         AvatarMixerType,
         AgentType,
+        VoxelServerType,
         AllTypes
     };
     
diff --git a/libraries/voxel-server-library/CMakeLists.txt b/libraries/voxel-server-library/CMakeLists.txt
new file mode 100644
index 0000000000..9eabb95508
--- /dev/null
+++ b/libraries/voxel-server-library/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 2.8)
+
+set(ROOT_DIR ../..)
+set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
+
+# setup for find modules
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
+
+set(TARGET_NAME voxel-server-library)
+
+find_package(Qt5Widgets REQUIRED)
+
+include(${MACRO_DIR}/SetupHifiLibrary.cmake)
+setup_hifi_library(${TARGET_NAME})
+
+qt5_use_modules(${TARGET_NAME} Widgets)
+
+include(${MACRO_DIR}/IncludeGLM.cmake)
+include_glm(${TARGET_NAME} ${ROOT_DIR})
+
+include(${MACRO_DIR}/LinkHifiLibrary.cmake)
+link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
+
+# link ZLIB
+find_package(ZLIB)
+include_directories(${ZLIB_INCLUDE_DIRS})
+target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
+
+# link in the shared library
+include(${MACRO_DIR}/LinkHifiLibrary.cmake)
+link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
+
+# link in the hifi voxels library
+link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
+
+# link in the hifi avatars library
+link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
diff --git a/voxel-server/src/NodeWatcher.cpp b/libraries/voxel-server-library/src/NodeWatcher.cpp
similarity index 100%
rename from voxel-server/src/NodeWatcher.cpp
rename to libraries/voxel-server-library/src/NodeWatcher.cpp
diff --git a/voxel-server/src/NodeWatcher.h b/libraries/voxel-server-library/src/NodeWatcher.h
similarity index 100%
rename from voxel-server/src/NodeWatcher.h
rename to libraries/voxel-server-library/src/NodeWatcher.h
diff --git a/voxel-server/src/VoxelNodeData.cpp b/libraries/voxel-server-library/src/VoxelNodeData.cpp
similarity index 100%
rename from voxel-server/src/VoxelNodeData.cpp
rename to libraries/voxel-server-library/src/VoxelNodeData.cpp
diff --git a/voxel-server/src/VoxelNodeData.h b/libraries/voxel-server-library/src/VoxelNodeData.h
similarity index 100%
rename from voxel-server/src/VoxelNodeData.h
rename to libraries/voxel-server-library/src/VoxelNodeData.h
diff --git a/voxel-server/src/VoxelPersistThread.cpp b/libraries/voxel-server-library/src/VoxelPersistThread.cpp
similarity index 100%
rename from voxel-server/src/VoxelPersistThread.cpp
rename to libraries/voxel-server-library/src/VoxelPersistThread.cpp
diff --git a/voxel-server/src/VoxelPersistThread.h b/libraries/voxel-server-library/src/VoxelPersistThread.h
similarity index 100%
rename from voxel-server/src/VoxelPersistThread.h
rename to libraries/voxel-server-library/src/VoxelPersistThread.h
diff --git a/voxel-server/src/VoxelSendThread.cpp b/libraries/voxel-server-library/src/VoxelSendThread.cpp
similarity index 99%
rename from voxel-server/src/VoxelSendThread.cpp
rename to libraries/voxel-server-library/src/VoxelSendThread.cpp
index 38f8c6f9b8..b9bb861349 100644
--- a/voxel-server/src/VoxelSendThread.cpp
+++ b/libraries/voxel-server-library/src/VoxelSendThread.cpp
@@ -11,9 +11,12 @@
 #include <NodeList.h>
 #include <SharedUtil.h>
 #include <PacketHeaders.h>
+#include <EnvironmentData.h>
+extern EnvironmentData environmentData[3];
 
 #include "VoxelSendThread.h"
 #include "VoxelServer.h"
+#include "VoxelServerState.h"
 
 VoxelSendThread::VoxelSendThread(uint16_t nodeID) :
     _nodeID(nodeID) {
diff --git a/voxel-server/src/VoxelSendThread.h b/libraries/voxel-server-library/src/VoxelSendThread.h
similarity index 100%
rename from voxel-server/src/VoxelSendThread.h
rename to libraries/voxel-server-library/src/VoxelSendThread.h
diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp
new file mode 100644
index 0000000000..b239a180d9
--- /dev/null
+++ b/libraries/voxel-server-library/src/VoxelServer.cpp
@@ -0,0 +1,349 @@
+//
+//  VoxelServer.cpp
+//  hifi
+//
+//  Created by Brad Hefta-Gaub on 9/16/13.
+//  Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
+//
+
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
+
+#include <OctalCode.h>
+#include <NodeList.h>
+#include <NodeTypes.h>
+#include <EnvironmentData.h>
+#include <VoxelTree.h>
+#include "VoxelNodeData.h"
+#include <SharedUtil.h>
+#include <PacketHeaders.h>
+#include <SceneUtils.h>
+#include <PerfStat.h>
+#include <JurisdictionSender.h>
+
+#include "NodeWatcher.h"
+#include "VoxelPersistThread.h"
+#include "VoxelSendThread.h"
+#include "VoxelServerPacketProcessor.h"
+
+#ifdef _WIN32
+#include "Syssocket.h"
+#include "Systime.h"
+#else
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <ifaddrs.h>
+#endif
+
+#include "VoxelServer.h"
+#include "VoxelServerState.h"
+
+const char* LOCAL_VOXELS_PERSIST_FILE = "resources/voxels.svo";
+const char* VOXELS_PERSIST_FILE = "/etc/highfidelity/voxel-server/resources/voxels.svo";
+char voxelPersistFilename[MAX_FILENAME_LENGTH];
+int PACKETS_PER_CLIENT_PER_INTERVAL = 10;
+VoxelTree serverTree(true); // this IS a reaveraging tree 
+bool wantVoxelPersist = true;
+bool wantLocalDomain = false;
+bool debugVoxelSending = false;
+bool shouldShowAnimationDebug = false;
+bool displayVoxelStats = false;
+bool debugVoxelReceiving = false;
+bool sendEnvironments = true;
+bool sendMinimalEnvironment = false;
+bool dumpVoxelsOnMove = false;
+EnvironmentData environmentData[3];
+int receivedPacketCount = 0;
+JurisdictionMap* jurisdiction = NULL;
+JurisdictionSender* jurisdictionSender = NULL;
+VoxelServerPacketProcessor* voxelServerPacketProcessor = NULL;
+VoxelPersistThread* voxelPersistThread = NULL;
+pthread_mutex_t treeLock;
+NodeWatcher nodeWatcher; // used to cleanup AGENT data when agents are killed
+
+int VoxelServer::_argc = 0;
+const char** VoxelServer::_argv = NULL;
+bool VoxelServer::_dontKillOnMissingDomain = false;
+
+void attachVoxelNodeDataToNode(Node* newNode) {
+    if (newNode->getLinkedData() == NULL) {
+        newNode->setLinkedData(new VoxelNodeData(newNode));
+    }
+}
+
+void VoxelServer::setArguments(int argc, char** argv) {
+    _argc = argc;
+    _argv = const_cast<const char**>(argv);
+}
+
+void VoxelServer::setupDomainAndPort(const char* domain, int port) {
+    NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, port);
+
+    // Handle Local Domain testing with the --local command line
+    const char* local = "--local";
+    ::wantLocalDomain = strcmp(domain, local) == 0;
+    if (::wantLocalDomain) {
+        printf("Local Domain MODE!\n");
+        NodeList::getInstance()->setDomainIPToLocalhost();
+    } else {
+        if (domain) {
+            NodeList::getInstance()->setDomainHostname(domain);
+        }
+    }
+    
+    // If we're running in standalone mode, we don't want to kill ourselves when we haven't heard from a domain
+    _dontKillOnMissingDomain = true;
+}
+
+//int main(int argc, const char * argv[]) {
+void VoxelServer::run() {
+    pthread_mutex_init(&::treeLock, NULL);
+    
+    qInstallMessageHandler(sharedMessageHandler);
+    
+    const char* JURISDICTION_FILE = "--jurisdictionFile";
+    const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
+    if (jurisdictionFile) {
+        printf("jurisdictionFile=%s\n", jurisdictionFile);
+
+        printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
+        jurisdiction = new JurisdictionMap(jurisdictionFile);
+        printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
+    } else {
+        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
+        const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
+        if (jurisdictionRoot) {
+            printf("jurisdictionRoot=%s\n", jurisdictionRoot);
+        }
+
+        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
+        const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
+        if (jurisdictionEndNodes) {
+            printf("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
+        }
+
+        if (jurisdictionRoot || jurisdictionEndNodes) {
+            ::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
+        }
+    }
+    
+    // should we send environments? Default is yes, but this command line suppresses sending
+    const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
+    ::dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
+    printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
+    
+    // should we send environments? Default is yes, but this command line suppresses sending
+    const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
+    bool dontSendEnvironments =  getCmdOption(_argc, _argv, DONT_SEND_ENVIRONMENTS);
+    if (dontSendEnvironments) {
+        printf("Sending environments suppressed...\n");
+        ::sendEnvironments = false;
+    } else { 
+        // should we send environments? Default is yes, but this command line suppresses sending
+        const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
+        ::sendMinimalEnvironment =  getCmdOption(_argc, _argv, MINIMAL_ENVIRONMENT);
+        printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
+    }
+    printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
+    
+    NodeList* nodeList = NodeList::getInstance();
+    nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);
+    
+    setvbuf(stdout, NULL, _IOLBF, 0);
+
+    // tell our NodeList about our desire to get notifications
+    nodeList->addHook(&nodeWatcher);
+    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
+
+    nodeList->startSilentNodeRemovalThread();
+    srand((unsigned)time(0));
+    
+    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
+    ::displayVoxelStats =  getCmdOption(_argc, _argv, DISPLAY_VOXEL_STATS);
+    printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));
+
+    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
+    ::debugVoxelSending =  getCmdOption(_argc, _argv, DEBUG_VOXEL_SENDING);
+    printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));
+
+    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
+    ::debugVoxelReceiving =  getCmdOption(_argc, _argv, DEBUG_VOXEL_RECEIVING);
+    printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));
+
+    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
+    ::shouldShowAnimationDebug =  getCmdOption(_argc, _argv, WANT_ANIMATION_DEBUG);
+    printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));
+
+    // By default we will voxel persist, if you want to disable this, then pass in this parameter
+    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
+    if ( getCmdOption(_argc, _argv, NO_VOXEL_PERSIST)) {
+        ::wantVoxelPersist = false;
+    }
+    printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));
+
+    // if we want Voxel Persistence, load the local file now...
+    bool persistantFileRead = false;
+    if (::wantVoxelPersist) {
+
+        // Check to see if the user passed in a command line option for setting packet send rate
+        const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
+        const char* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
+        if (voxelsPersistFilenameParameter) {
+            strcpy(voxelPersistFilename, voxelsPersistFilenameParameter);
+        } else {
+            //strcpy(voxelPersistFilename, ::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
+            strcpy(voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
+        }
+
+        printf("loading voxels from file: %s...\n", voxelPersistFilename);
+
+        persistantFileRead = ::serverTree.readFromSVOFile(::voxelPersistFilename);
+        if (persistantFileRead) {
+            PerformanceWarning warn(::shouldShowAnimationDebug,
+                                    "persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
+            
+            // after done inserting all these voxels, then reaverage colors
+            serverTree.reaverageVoxelColors(serverTree.rootNode);
+            printf("Voxels reAveraged\n");
+        }
+        
+        ::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
+        printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
+        unsigned long nodeCount         = ::serverTree.rootNode->getSubTreeNodeCount();
+        unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
+        unsigned long leafNodeCount     = ::serverTree.rootNode->getSubTreeLeafNodeCount();
+        printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
+        
+        // now set up VoxelPersistThread
+        ::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename);
+        if (::voxelPersistThread) {
+            ::voxelPersistThread->initialize(true);
+        }
+    }
+
+    // Check to see if the user passed in a command line option for loading an old style local
+    // Voxel File. If so, load it now. This is not the same as a voxel persist file
+    const char* INPUT_FILE = "-i";
+    const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
+    if (voxelsFilename) {
+        serverTree.readFromSVOFile(voxelsFilename);
+    }
+
+    // Check to see if the user passed in a command line option for setting packet send rate
+    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
+    const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
+    if (packetsPerSecond) {
+        PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
+        if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
+            PACKETS_PER_CLIENT_PER_INTERVAL = 1;
+        }
+        printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
+    }
+    
+    // for now, initialize the environments with fixed values
+    environmentData[1].setID(1);
+    environmentData[1].setGravity(1.0f);
+    environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
+    environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
+    environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
+    environmentData[2].setID(2);
+    environmentData[2].setGravity(1.0f);
+    environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
+    environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
+    environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
+    environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
+
+    sockaddr senderAddress;
+    
+    unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
+    ssize_t packetLength;
+    
+    timeval lastDomainServerCheckIn = {};
+
+    // set up our jurisdiction broadcaster...
+    ::jurisdictionSender = new JurisdictionSender(::jurisdiction);
+    if (::jurisdictionSender) {
+        ::jurisdictionSender->initialize(true);
+    }
+    
+    // set up our VoxelServerPacketProcessor
+    ::voxelServerPacketProcessor = new VoxelServerPacketProcessor();
+    if (::voxelServerPacketProcessor) {
+        ::voxelServerPacketProcessor->initialize(true);
+    }
+
+    // loop to send to nodes requesting data
+    while (true) {
+    
+        if (!_dontKillOnMissingDomain &&
+            NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
+            break;
+        }
+        
+        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
+        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
+            gettimeofday(&lastDomainServerCheckIn, NULL);
+            NodeList::getInstance()->sendDomainServerCheckIn();
+        }
+        
+        if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
+            packetVersionMatch(packetData)) {
+
+            int numBytesPacketHeader = numBytesForPacketHeader(packetData);
+
+            if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
+                // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
+                // need to make sure we have it in our nodeList.
+                uint16_t nodeID = 0;
+                unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
+                Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
+                                                       &senderAddress,
+                                                       NODE_TYPE_AGENT,
+                                                       nodeID);
+
+                NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
+            } else if (packetData[0] == PACKET_TYPE_PING) {
+                // If the packet is a ping, let processNodeData handle it.
+                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
+            } else if (packetData[0] == PACKET_TYPE_DOMAIN) {
+                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
+            } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
+                if (::jurisdictionSender) {
+                    ::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
+                }
+            } else if (::voxelServerPacketProcessor) {
+                ::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
+            } else {
+                printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
+            }
+        }
+    }
+    
+    if (::jurisdiction) {
+        delete ::jurisdiction;
+    }
+    
+    if (::jurisdictionSender) {
+        ::jurisdictionSender->terminate();
+        delete ::jurisdictionSender;
+    }
+
+    if (::voxelServerPacketProcessor) {
+        ::voxelServerPacketProcessor->terminate();
+        delete ::voxelServerPacketProcessor;
+    }
+
+    if (::voxelPersistThread) {
+        ::voxelPersistThread->terminate();
+        delete ::voxelPersistThread;
+    }
+    
+    // tell our NodeList we're done with notifications
+    nodeList->removeHook(&nodeWatcher);
+    
+    pthread_mutex_destroy(&::treeLock);
+}
+
+
diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h
new file mode 100644
index 0000000000..d51870dbb1
--- /dev/null
+++ b/libraries/voxel-server-library/src/VoxelServer.h
@@ -0,0 +1,36 @@
+//  VoxelServer.h
+//  voxel-server
+//
+//  Created by Brad Hefta-Gaub on 8/21/13
+//  Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
+//
+//
+
+#ifndef __voxel_server__VoxelServer__
+#define __voxel_server__VoxelServer__
+
+/// Handles assignments of type VoxelServer - sending voxels to various clients.
+class VoxelServer {
+public:
+    /// runs the voxel server assignment
+    static void run();
+    
+    /// allows setting of run arguments
+    static void setArguments(int argc, char** argv);
+
+    /// when VoxelServer class is used by voxel-server stand alone executable it calls this to specify the domain
+    /// and port it is handling. When called by assignment-client, this is not needed because assignment-client
+    /// handles ports and domains automatically.
+    /// \param const char* domain domain name, IP address, or local to specify the domain the voxel server is serving
+    /// \param int port port the voxel server will listen on
+    static void setupDomainAndPort(const char* domain, int port);
+    
+private:
+    static int _argc;
+    static const char** _argv;
+    static bool _dontKillOnMissingDomain;
+};
+
+
+
+#endif // __voxel_server__VoxelServer__
diff --git a/voxel-server/src/VoxelServerPacketProcessor.cpp b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp
similarity index 99%
rename from voxel-server/src/VoxelServerPacketProcessor.cpp
rename to libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp
index aaa347ee86..d283296e6f 100644
--- a/voxel-server/src/VoxelServerPacketProcessor.cpp
+++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp
@@ -12,6 +12,7 @@
 #include <PerfStat.h>
 
 #include "VoxelServer.h"
+#include "VoxelServerState.h"
 #include "VoxelServerPacketProcessor.h"
 
 
diff --git a/voxel-server/src/VoxelServerPacketProcessor.h b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h
similarity index 100%
rename from voxel-server/src/VoxelServerPacketProcessor.h
rename to libraries/voxel-server-library/src/VoxelServerPacketProcessor.h
diff --git a/voxel-server/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServerState.h
similarity index 88%
rename from voxel-server/src/VoxelServer.h
rename to libraries/voxel-server-library/src/VoxelServerState.h
index 0f4c8577db..2d00d4a046 100644
--- a/voxel-server/src/VoxelServer.h
+++ b/libraries/voxel-server-library/src/VoxelServerState.h
@@ -6,12 +6,11 @@
 //
 //
 
-#ifndef __voxel_server__VoxelServer__
-#define __voxel_server__VoxelServer__
+#ifndef __voxel_server__VoxelServerState__
+#define __voxel_server__VoxelServerState__
 
 #include <SharedUtil.h>
 #include <NodeList.h> // for MAX_PACKET_SIZE
-#include <EnvironmentData.h>
 #include <JurisdictionSender.h>
 #include <VoxelTree.h>
 
@@ -19,7 +18,6 @@
 
 
 const int MAX_FILENAME_LENGTH = 1024;
-const int VOXEL_LISTEN_PORT = 40106;
 const int VOXEL_SIZE_BYTES = 3 + (3 * sizeof(float));
 const int VOXELS_PER_PACKET = (MAX_PACKET_SIZE - 1) / VOXEL_SIZE_BYTES;
 const int MIN_BRIGHTNESS = 64;
@@ -46,13 +44,10 @@ extern bool debugVoxelReceiving;
 extern bool sendEnvironments;
 extern bool sendMinimalEnvironment;
 extern bool dumpVoxelsOnMove;
-extern EnvironmentData environmentData[3];
 extern int receivedPacketCount;
 extern JurisdictionMap* jurisdiction;
 extern JurisdictionSender* jurisdictionSender;
 extern VoxelServerPacketProcessor* voxelServerPacketProcessor;
 extern pthread_mutex_t treeLock;
 
-
-
-#endif // __voxel_server__VoxelServer__
+#endif // __voxel_server__VoxelServerState__
diff --git a/libraries/voxels/src/VoxelConstants.h b/libraries/voxels/src/VoxelConstants.h
index 5a5815b6b3..08fdbefee3 100644
--- a/libraries/voxels/src/VoxelConstants.h
+++ b/libraries/voxels/src/VoxelConstants.h
@@ -24,8 +24,10 @@ const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f,-1.0f);
 const bool LOW_RES_MONO = false; // while in "low res mode" do voxels switch to monochrome
 const uint64_t CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
 
-const int   TREE_SCALE = 128; // This is the number of meters of the 0.0 to 1.0 voxel universe
-const float VOXEL_SIZE_SCALE = 50000.0f; // This controls the LOD bigger will make smaller voxels visible at greater distance
+const int   TREE_SCALE = 16384; // ~10 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe
+
+// This controls the LOD. Larger number will make smaller voxels visible at greater distance.
+const float VOXEL_SIZE_SCALE = TREE_SCALE * 400.0f; 
 
 const int NUMBER_OF_CHILDREN = 8;
 const int MAX_VOXEL_PACKET_SIZE = 1492;
diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt
index c401a8033c..f759db0d89 100644
--- a/voxel-server/CMakeLists.txt
+++ b/voxel-server/CMakeLists.txt
@@ -26,3 +26,5 @@ link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR})
 # link in the hifi avatars library
 link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR})
 
+# link in the hifi voxel-server-library
+link_hifi_library(voxel-server-library ${TARGET_NAME} ${ROOT_DIR})
diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp
index 56ea5003e1..f854df84cf 100644
--- a/voxel-server/src/main.cpp
+++ b/voxel-server/src/main.cpp
@@ -6,73 +6,18 @@
 //  Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
 //
 
-#include <cmath>
-#include <cstdlib>
-#include <cstring>
-#include <cstdio>
-
-#include <OctalCode.h>
-#include <NodeList.h>
-#include <NodeTypes.h>
-#include <EnvironmentData.h>
-#include <VoxelTree.h>
-#include "VoxelNodeData.h"
 #include <SharedUtil.h>
-#include <PacketHeaders.h>
-#include <SceneUtils.h>
-#include <PerfStat.h>
-#include <JurisdictionSender.h>
+#include <VoxelServer.h>
+const int VOXEL_LISTEN_PORT = 40106;
 
-#include "NodeWatcher.h"
-#include "VoxelPersistThread.h"
-#include "VoxelSendThread.h"
-#include "VoxelServerPacketProcessor.h"
-
-#ifdef _WIN32
-#include "Syssocket.h"
-#include "Systime.h"
-#else
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <ifaddrs.h>
-#endif
-
-#include "VoxelServer.h"
-
-const char* LOCAL_VOXELS_PERSIST_FILE = "resources/voxels.svo";
-const char* VOXELS_PERSIST_FILE = "/etc/highfidelity/voxel-server/resources/voxels.svo";
-char voxelPersistFilename[MAX_FILENAME_LENGTH];
-int PACKETS_PER_CLIENT_PER_INTERVAL = 10;
-VoxelTree serverTree(true); // this IS a reaveraging tree 
-bool wantVoxelPersist = true;
-bool wantLocalDomain = false;
-bool debugVoxelSending = false;
-bool shouldShowAnimationDebug = false;
-bool displayVoxelStats = false;
-bool debugVoxelReceiving = false;
-bool sendEnvironments = true;
-bool sendMinimalEnvironment = false;
-bool dumpVoxelsOnMove = false;
-EnvironmentData environmentData[3];
-int receivedPacketCount = 0;
-JurisdictionMap* jurisdiction = NULL;
-JurisdictionSender* jurisdictionSender = NULL;
-VoxelServerPacketProcessor* voxelServerPacketProcessor = NULL;
-VoxelPersistThread* voxelPersistThread = NULL;
-pthread_mutex_t treeLock;
-NodeWatcher nodeWatcher; // used to cleanup AGENT data when agents are killed
-
-void attachVoxelNodeDataToNode(Node* newNode) {
-    if (newNode->getLinkedData() == NULL) {
-        newNode->setLinkedData(new VoxelNodeData(newNode));
-    }
-}
 
 int main(int argc, const char * argv[]) {
-    pthread_mutex_init(&::treeLock, NULL);
-    
-    qInstallMessageHandler(sharedMessageHandler);
-    
+
+    // Handle Local Domain testing with the --local command line
+    const char* local = "--local";
+    bool wantLocalDomain = cmdOptionExists(argc, argv, local);
+    const char* domainIP = getCmdOption(argc, argv, "--domain");
+
     int listenPort = VOXEL_LISTEN_PORT;
     // Check to see if the user passed in a command line option for setting listen port
     const char* PORT_PARAMETER = "--port";
@@ -85,255 +30,16 @@ int main(int argc, const char * argv[]) {
         printf("portParameter=%s listenPort=%d\n", portParameter, listenPort);
     }
 
-    const char* JURISDICTION_FILE = "--jurisdictionFile";
-    const char* jurisdictionFile = getCmdOption(argc, argv, JURISDICTION_FILE);
-    if (jurisdictionFile) {
-        printf("jurisdictionFile=%s\n", jurisdictionFile);
-
-        printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
-        jurisdiction = new JurisdictionMap(jurisdictionFile);
-        printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
+    if (wantLocalDomain) {
+        VoxelServer::setupDomainAndPort(local, listenPort);
     } else {
-        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
-        const char* jurisdictionRoot = getCmdOption(argc, argv, JURISDICTION_ROOT);
-        if (jurisdictionRoot) {
-            printf("jurisdictionRoot=%s\n", jurisdictionRoot);
-        }
-
-        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
-        const char* jurisdictionEndNodes = getCmdOption(argc, argv, JURISDICTION_ENDNODES);
-        if (jurisdictionEndNodes) {
-            printf("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
-        }
-
-        if (jurisdictionRoot || jurisdictionEndNodes) {
-            ::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
-        }
-    }
-    
-    // should we send environments? Default is yes, but this command line suppresses sending
-    const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
-    ::dumpVoxelsOnMove = cmdOptionExists(argc, argv, DUMP_VOXELS_ON_MOVE);
-    printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
-    
-    // should we send environments? Default is yes, but this command line suppresses sending
-    const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
-    bool dontSendEnvironments = cmdOptionExists(argc, argv, DONT_SEND_ENVIRONMENTS);
-    if (dontSendEnvironments) {
-        printf("Sending environments suppressed...\n");
-        ::sendEnvironments = false;
-    } else { 
-        // should we send environments? Default is yes, but this command line suppresses sending
-        const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
-        ::sendMinimalEnvironment = cmdOptionExists(argc, argv, MINIMAL_ENVIRONMENT);
-        printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
-    }
-    printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
-    
-    NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort);
-    setvbuf(stdout, NULL, _IOLBF, 0);
-    
-    // tell our NodeList about our desire to get notifications
-    nodeList->addHook(&nodeWatcher);
-
-    // Handle Local Domain testing with the --local command line
-    const char* local = "--local";
-    ::wantLocalDomain = cmdOptionExists(argc, argv,local);
-    if (::wantLocalDomain) {
-        printf("Local Domain MODE!\n");
-        nodeList->setDomainIPToLocalhost();
-    } else {
-        const char* domainIP = getCmdOption(argc, argv, "--domain");
         if (domainIP) {
-            NodeList::getInstance()->setDomainHostname(domainIP);
+            VoxelServer::setupDomainAndPort(domainIP, listenPort);
         }
     }
 
-    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
-    nodeList->startSilentNodeRemovalThread();
-    
-    srand((unsigned)time(0));
-    
-    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
-    ::displayVoxelStats = cmdOptionExists(argc, argv, DISPLAY_VOXEL_STATS);
-    printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));
-
-    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
-    ::debugVoxelSending = cmdOptionExists(argc, argv, DEBUG_VOXEL_SENDING);
-    printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));
-
-    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
-    ::debugVoxelReceiving = cmdOptionExists(argc, argv, DEBUG_VOXEL_RECEIVING);
-    printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));
-
-    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
-    ::shouldShowAnimationDebug = cmdOptionExists(argc, argv, WANT_ANIMATION_DEBUG);
-    printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));
-
-    // By default we will voxel persist, if you want to disable this, then pass in this parameter
-    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
-    if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) {
-        ::wantVoxelPersist = false;
-    }
-    printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));
-
-    // if we want Voxel Persistence, load the local file now...
-    bool persistantFileRead = false;
-    if (::wantVoxelPersist) {
-
-        // Check to see if the user passed in a command line option for setting packet send rate
-        const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
-        const char* voxelsPersistFilenameParameter = getCmdOption(argc, argv, VOXELS_PERSIST_FILENAME);
-        if (voxelsPersistFilenameParameter) {
-            strcpy(voxelPersistFilename, voxelsPersistFilenameParameter);
-        } else {
-            strcpy(voxelPersistFilename, ::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
-        }
-
-        printf("loading voxels from file: %s...\n", voxelPersistFilename);
-
-        persistantFileRead = ::serverTree.readFromSVOFile(::voxelPersistFilename);
-        if (persistantFileRead) {
-            PerformanceWarning warn(::shouldShowAnimationDebug,
-                                    "persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
-            
-            // after done inserting all these voxels, then reaverage colors
-            serverTree.reaverageVoxelColors(serverTree.rootNode);
-            printf("Voxels reAveraged\n");
-        }
-        
-        ::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
-        printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
-        unsigned long nodeCount         = ::serverTree.rootNode->getSubTreeNodeCount();
-        unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
-        unsigned long leafNodeCount     = ::serverTree.rootNode->getSubTreeLeafNodeCount();
-        printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
-        
-        // now set up VoxelPersistThread
-        ::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename);
-        if (::voxelPersistThread) {
-            ::voxelPersistThread->initialize(true);
-        }
-    }
-
-    // Check to see if the user passed in a command line option for loading an old style local
-    // Voxel File. If so, load it now. This is not the same as a voxel persist file
-    const char* INPUT_FILE = "-i";
-    const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE);
-    if (voxelsFilename) {
-        serverTree.readFromSVOFile(voxelsFilename);
-    }
-
-    // Check to see if the user passed in a command line option for setting packet send rate
-    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
-    const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND);
-    if (packetsPerSecond) {
-        PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
-        if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
-            PACKETS_PER_CLIENT_PER_INTERVAL = 1;
-        }
-        printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
-    }
-    
-    // for now, initialize the environments with fixed values
-    environmentData[1].setID(1);
-    environmentData[1].setGravity(1.0f);
-    environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
-    environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
-    environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
-    environmentData[2].setID(2);
-    environmentData[2].setGravity(1.0f);
-    environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
-    environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
-    environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
-    environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
-
-    sockaddr senderAddress;
-    
-    unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
-    ssize_t packetLength;
-    
-    timeval lastDomainServerCheckIn = {};
-
-    // set up our jurisdiction broadcaster...
-    ::jurisdictionSender = new JurisdictionSender(::jurisdiction);
-    if (::jurisdictionSender) {
-        ::jurisdictionSender->initialize(true);
-    }
-    
-    // set up our VoxelServerPacketProcessor
-    ::voxelServerPacketProcessor = new VoxelServerPacketProcessor();
-    if (::voxelServerPacketProcessor) {
-        ::voxelServerPacketProcessor->initialize(true);
-    }
-
-    // loop to send to nodes requesting data
-    while (true) {
-
-        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
-        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
-            gettimeofday(&lastDomainServerCheckIn, NULL);
-            NodeList::getInstance()->sendDomainServerCheckIn();
-        }
-        
-        if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
-            packetVersionMatch(packetData)) {
-
-            int numBytesPacketHeader = numBytesForPacketHeader(packetData);
-
-            if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
-                // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
-                // need to make sure we have it in our nodeList.
-                uint16_t nodeID = 0;
-                unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
-                Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
-                                                       &senderAddress,
-                                                       NODE_TYPE_AGENT,
-                                                       nodeID);
-
-                NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
-            } else if (packetData[0] == PACKET_TYPE_PING) {
-                // If the packet is a ping, let processNodeData handle it.
-                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
-            } else if (packetData[0] == PACKET_TYPE_DOMAIN) {
-                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
-            } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
-                if (::jurisdictionSender) {
-                    ::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
-                }
-            } else if (::voxelServerPacketProcessor) {
-                ::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
-            } else {
-                printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
-            }
-        }
-    }
-    
-    if (::jurisdiction) {
-        delete ::jurisdiction;
-    }
-    
-    if (::jurisdictionSender) {
-        ::jurisdictionSender->terminate();
-        delete ::jurisdictionSender;
-    }
-
-    if (::voxelServerPacketProcessor) {
-        ::voxelServerPacketProcessor->terminate();
-        delete ::voxelServerPacketProcessor;
-    }
-
-    if (::voxelPersistThread) {
-        ::voxelPersistThread->terminate();
-        delete ::voxelPersistThread;
-    }
-    
-    // tell our NodeList we're done with notifications
-    nodeList->removeHook(&nodeWatcher);
-    
-    pthread_mutex_destroy(&::treeLock);
-
-    return 0;
+    VoxelServer::setArguments(argc, const_cast<char**>(argv));
+    VoxelServer::run();
 }