diff --git a/Apps/Sandcastle/gallery/DataSource Ordering.html b/Apps/Sandcastle/gallery/DataSource Ordering.html
new file mode 100644
index 000000000000..d659892a4635
--- /dev/null
+++ b/Apps/Sandcastle/gallery/DataSource Ordering.html	
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
+    <meta name="description" content="Change the order in which DataSources draw ground primitives">
+    <meta name="cesium-sandcastle-labels" content="DataSources">
+    <title>Cesium Demo</title>
+    <script type="text/javascript" src="../Sandcastle-header.js"></script>
+    <script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.20/require.js"></script>
+    <script type="text/javascript">
+        if(typeof require === "function") {
+            require.config({
+                baseUrl : '../../../Source',
+                waitSeconds : 120
+            });
+        }
+    </script>
+</head>
+<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
+<style>
+    @import url(../templates/bucket.css);
+</style>
+<div id="cesiumContainer" class="fullSize"></div>
+<div id="loadingOverlay"><h1>Loading...</h1></div>
+<div id="toolbar"></div>
+<script id="cesium_sandcastle_script">
+function startup(Cesium) {
+    'use strict';
+//Sandcastle_Begin
+var czml1 = [{
+    "id" : "document",
+    "name" : "CZML Geometries: Rectangle",
+    "version" : "1.0"
+}, {
+    "rectangle" : {
+        "coordinates" : {
+            "wsenDegrees" : [-120, 40, -110, 50]
+        },
+        "fill" : true,
+        "material" : {
+            "solidColor" : {
+                "color": {
+                    "rgba" : [255, 0, 0, 255]
+                }
+            }
+        }
+    }
+}, {
+    "rectangle" : {
+        "coordinates" : {
+            "wsenDegrees" : [-110, 40, -100, 50]
+        },
+        "fill" : true,
+        "material" : {
+            "solidColor" : {
+                "color": {
+                    "rgba" : [0, 0, 255, 255]
+                }
+            }
+        }
+    }
+}];
+
+var czml2 = [{
+    "id" : "document",
+    "name" : "CZML Geometries: Rectangle",
+    "version" : "1.0"
+}, {
+    "rectangle" : {
+        "coordinates" : {
+            "wsenDegrees" : [-120, 45, -110, 55]
+        },
+        "fill" : true,
+        "material" : {
+            "solidColor" : {
+                "color": {
+                    "rgba" : [255, 255, 0, 255]
+                }
+            }
+        }
+    }
+}, {
+    "rectangle" : {
+        "coordinates" : {
+            "wsenDegrees" : [-110, 45, -100, 55]
+        },
+        "fill" : true,
+        "material" : {
+            "solidColor" : {
+                "color": {
+                    "rgba" : [0, 255, 255, 255]
+                }
+            }
+        }
+    }
+}];
+
+var viewer = new Cesium.Viewer('cesiumContainer');
+var promise1 = Cesium.CzmlDataSource.load(czml1);
+viewer.dataSources.add(promise1);
+var promise2 = Cesium.CzmlDataSource.load(czml2);
+viewer.dataSources.add(promise2);
+
+Sandcastle.addToolbarButton('Swap', function() {
+    Cesium.when.all([promise1, promise2])
+    .then(function(results) {
+        var ds1 = results[0];
+        var ds2 = results[1];
+        if (viewer.dataSources.indexOf(ds1) === 0) {
+            viewer.dataSources.raise(ds1);
+        } else {
+            viewer.dataSources.lower(ds1);
+        }
+    });
+});//Sandcastle_End
+    Sandcastle.finishedLoading();
+}
+if (typeof Cesium !== "undefined") {
+    startup(Cesium);
+} else if (typeof require === "function") {
+    require(["Cesium"], startup);
+}
+</script>
+</body>
+</html>
diff --git a/Apps/Sandcastle/gallery/DataSource Ordering.jpg b/Apps/Sandcastle/gallery/DataSource Ordering.jpg
new file mode 100644
index 000000000000..4e6e791db414
Binary files /dev/null and b/Apps/Sandcastle/gallery/DataSource Ordering.jpg differ
diff --git a/CHANGES.md b/CHANGES.md
index 53393336c438..c957c2e6faf9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,9 @@ Change Log
 
 ### 1.44 - 2018-04-02
 
+##### Breaking Changes :mega:
+* `GeometryVisualizer` now requires `primitive` and `groundPrimitive` parameters. [#6316](https://github.com/AnalyticalGraphicsInc/cesium/pull/6316)
+
 ##### Deprecated :hourglass_flowing_sand:
 * `ClippingPlaneCollection` is now supported in Internet Explorer, so `ClippingPlaneCollection.isSupported` has been deprecated and will be removed in Cesium 1.45.
 * `ClippingPlaneCollection` should now be used with `ClippingPlane` objects instead of `Plane`. Use of `Plane` objects has been deprecated and will be removed in Cesium 1.45.
@@ -20,6 +23,9 @@ Change Log
   * sourceType specifies the type of data source if the URL doesn't have a known file extension.
   * flyTo=false optionally disables the automatic flyTo after loading the data source.
 * Added a multi-part CZML example to Sandcastle. [#6320](https://github.com/AnalyticalGraphicsInc/cesium/pull/6320)
+* Added support for ordering in `DataSourceCollection` [#6316](https://github.com/AnalyticalGraphicsInc/cesium/pull/6316)
+  * All ground geometry from one `DataSource` will render in front of all ground geometry from another `DataSource` in the same collection with a lower index.
+  * Use `DataSourceCollection.raise`, `DataSourceCollection.lower`, `DataSourceCollection.raiseToTop` and `DataSourceCollection.lowerToBottom` functions to change the ordering of a `DataSource` in the collection. 
 
 ##### Fixes :wrench:
 * Fixed support of glTF-supplied tangent vectors. [#6302](https://github.com/AnalyticalGraphicsInc/cesium/pull/6302)
diff --git a/Source/DataSources/DataSourceCollection.js b/Source/DataSources/DataSourceCollection.js
index 3dc03d305cc7..6edc92de4d27 100644
--- a/Source/DataSources/DataSourceCollection.js
+++ b/Source/DataSources/DataSourceCollection.js
@@ -5,6 +5,7 @@ define([
         '../Core/destroyObject',
         '../Core/DeveloperError',
         '../Core/Event',
+        '../Core/Math',
         '../ThirdParty/when'
     ], function(
         defaultValue,
@@ -13,6 +14,7 @@ define([
         destroyObject,
         DeveloperError,
         Event,
+        CesiumMath,
         when) {
     'use strict';
 
@@ -25,6 +27,7 @@ define([
         this._dataSources = [];
         this._dataSourceAdded = new Event();
         this._dataSourceRemoved = new Event();
+        this._dataSourceMoved = new Event();
     }
 
     defineProperties(DataSourceCollection.prototype, {
@@ -64,6 +67,19 @@ define([
             get : function() {
                 return this._dataSourceRemoved;
             }
+        },
+
+        /**
+         * An event that is raised when a data source changes position in the collection.  Event handlers are passed the data source
+         * that was moved, its new index after the move, and its old index prior to the move.
+         * @memberof DataSourceCollection.prototype
+         * @type {Event}
+         * @readonly
+         */
+        dataSourceMoved : {
+            get : function() {
+                return this._dataSourceMoved;
+            }
         }
     });
 
@@ -177,6 +193,105 @@ define([
         return this._dataSources[index];
     };
 
+    function getIndex(dataSources, dataSource) {
+        //>>includeStart('debug', pragmas.debug);
+        if (!defined(dataSource)) {
+            throw new DeveloperError('dataSource is required.');
+        }
+        //>>includeEnd('debug');
+
+        var index = dataSources.indexOf(dataSource);
+
+        //>>includeStart('debug', pragmas.debug);
+        if (index === -1) {
+            throw new DeveloperError('dataSource is not in this collection.');
+        }
+        //>>includeEnd('debug');
+
+        return index;
+    }
+
+    function swapDataSources(collection, i, j) {
+        var arr = collection._dataSources;
+        var length = arr.length - 1;
+        i = CesiumMath.clamp(i, 0, length);
+        j = CesiumMath.clamp(j, 0, length);
+
+        if (i === j) {
+            return;
+        }
+
+        var temp = arr[i];
+        arr[i] = arr[j];
+        arr[j] = temp;
+
+        collection.dataSourceMoved.raiseEvent(temp, j, i);
+    }
+
+    /**
+     * Raises a data source up one position in the collection.
+     *
+     * @param {DataSource} dataSource The data source to move.
+     *
+     * @exception {DeveloperError} dataSource is not in this collection.
+     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
+     */
+    DataSourceCollection.prototype.raise = function(dataSource) {
+        var index = getIndex(this._dataSources, dataSource);
+        swapDataSources(this, index, index + 1);
+    };
+
+    /**
+     * Lowers a data source down one position in the collection.
+     *
+     * @param {DataSource} dataSource The data source to move.
+     *
+     * @exception {DeveloperError} dataSource is not in this collection.
+     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
+     */
+    DataSourceCollection.prototype.lower = function(dataSource) {
+        var index = getIndex(this._dataSources, dataSource);
+        swapDataSources(this, index, index - 1);
+    };
+
+    /**
+     * Raises a data source to the top of the collection.
+     *
+     * @param {DataSource} dataSource The data source to move.
+     *
+     * @exception {DeveloperError} dataSource is not in this collection.
+     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
+     */
+    DataSourceCollection.prototype.raiseToTop = function(dataSource) {
+        var index = getIndex(this._dataSources, dataSource);
+        if (index === this._dataSources.length - 1) {
+            return;
+        }
+        this._dataSources.splice(index, 1);
+        this._dataSources.push(dataSource);
+
+        this.dataSourceMoved.raiseEvent(dataSource, this._dataSources.length - 1, index);
+    };
+
+    /**
+     * Lowers a data source to the bottom of the collection.
+     *
+     * @param {DataSource} dataSource The data source to move.
+     *
+     * @exception {DeveloperError} dataSource is not in this collection.
+     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
+     */
+    DataSourceCollection.prototype.lowerToBottom = function(dataSource) {
+        var index = getIndex(this._dataSources, dataSource);
+        if (index === 0) {
+            return;
+        }
+        this._dataSources.splice(index, 1);
+        this._dataSources.splice(0, 0, dataSource);
+
+        this.dataSourceMoved.raiseEvent(dataSource, 0, index);
+    };
+
     /**
      * Returns true if this object was destroyed; otherwise, false.
      * If this object was destroyed, it should not be used; calling any function other than
diff --git a/Source/DataSources/DataSourceDisplay.js b/Source/DataSources/DataSourceDisplay.js
index 9fc1c0d125bd..ba4d35735f06 100644
--- a/Source/DataSources/DataSourceDisplay.js
+++ b/Source/DataSources/DataSourceDisplay.js
@@ -8,6 +8,7 @@ define([
         '../Core/DeveloperError',
         '../Core/EventHelper',
         '../Scene/GroundPrimitive',
+        '../Scene/PrimitiveCollection',
         './BillboardVisualizer',
         './BoundingSphereState',
         './CustomDataSource',
@@ -27,6 +28,7 @@ define([
         DeveloperError,
         EventHelper,
         GroundPrimitive,
+        PrimitiveCollection,
         BillboardVisualizer,
         BoundingSphereState,
         CustomDataSource,
@@ -65,11 +67,25 @@ define([
         this._eventHelper = new EventHelper();
         this._eventHelper.add(dataSourceCollection.dataSourceAdded, this._onDataSourceAdded, this);
         this._eventHelper.add(dataSourceCollection.dataSourceRemoved, this._onDataSourceRemoved, this);
+        this._eventHelper.add(dataSourceCollection.dataSourceMoved, this._onDataSourceMoved, this);
 
         this._dataSourceCollection = dataSourceCollection;
         this._scene = scene;
         this._visualizersCallback = defaultValue(options.visualizersCallback, DataSourceDisplay.defaultVisualizersCallback);
 
+        var primitivesAdded = false;
+        var primitives = new PrimitiveCollection();
+        var groundPrimitives = new PrimitiveCollection();
+
+        if (dataSourceCollection.length > 0) {
+            scene.primitives.add(primitives);
+            scene.groundPrimitives.add(groundPrimitives);
+            primitivesAdded = true;
+        }
+
+        this._primitives = primitives;
+        this._groundPrimitives = groundPrimitives;
+
         for (var i = 0, len = dataSourceCollection.length; i < len; i++) {
             this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i));
         }
@@ -78,6 +94,25 @@ define([
         this._onDataSourceAdded(undefined, defaultDataSource);
         this._defaultDataSource = defaultDataSource;
 
+        var removeDefaultDataSoureListener;
+        var removeDataSourceCollectionListener;
+        if (!primitivesAdded) {
+            var that = this;
+            var addPrimitives = function() {
+                scene.primitives.add(primitives);
+                scene.groundPrimitives.add(groundPrimitives);
+                removeDefaultDataSoureListener();
+                removeDataSourceCollectionListener();
+                that._removeDefaultDataSoureListener = undefined;
+                that._removeDataSourceCollectionListener = undefined;
+            };
+            removeDefaultDataSoureListener = defaultDataSource.entities.collectionChanged.addEventListener(addPrimitives);
+            removeDataSourceCollectionListener = dataSourceCollection.dataSourceAdded.addEventListener(addPrimitives);
+        }
+
+        this._removeDefaultDataSoureListener = removeDefaultDataSoureListener;
+        this._removeDataSourceCollectionListener = removeDataSourceCollectionListener;
+
         this._ready = false;
     }
 
@@ -90,7 +125,7 @@ define([
     DataSourceDisplay.defaultVisualizersCallback = function(scene, entityCluster, dataSource) {
         var entities = dataSource.entities;
         return [new BillboardVisualizer(entityCluster, entities),
-                new GeometryVisualizer(scene, entities),
+                new GeometryVisualizer(scene, entities, dataSource._primitives, dataSource._groundPrimitives),
                 new LabelVisualizer(entityCluster, entities),
                 new ModelVisualizer(scene, entities),
                 new PointVisualizer(entityCluster, entities),
@@ -185,6 +220,14 @@ define([
         }
         this._onDataSourceRemoved(undefined, this._defaultDataSource);
 
+        if (defined(this._removeDefaultDataSoureListener)) {
+            this._removeDefaultDataSoureListener();
+            this._removeDataSourceCollectionListener();
+        } else {
+            this._scene.primitives.remove(this._primitives);
+            this._scene.groundPrimitives.remove(this._groundPrimitives);
+        }
+
         return destroyObject(this);
     };
 
@@ -317,18 +360,32 @@ define([
     DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource) {
         var scene = this._scene;
 
+        var displayPrimitives = this._primitives;
+        var displayGroundPrimitives = this._groundPrimitives;
+
+        var primitives = displayPrimitives.add(new PrimitiveCollection());
+        var groundPrimitives = displayGroundPrimitives.add(new PrimitiveCollection());
+
+        dataSource._primitives = primitives;
+        dataSource._groundPrimitives = groundPrimitives;
+
         var entityCluster = dataSource.clustering;
         entityCluster._initialize(scene);
 
-        scene.primitives.add(entityCluster);
+        primitives.add(entityCluster);
 
         dataSource._visualizers = this._visualizersCallback(scene, entityCluster, dataSource);
     };
 
     DataSourceDisplay.prototype._onDataSourceRemoved = function(dataSourceCollection, dataSource) {
-        var scene = this._scene;
+        var displayPrimitives = this._primitives;
+        var displayGroundPrimitives = this._groundPrimitives;
+
+        var primitives = dataSource._primitives;
+        var groundPrimitives = dataSource._groundPrimitives;
+
         var entityCluster = dataSource.clustering;
-        scene.primitives.remove(entityCluster);
+        primitives.remove(entityCluster);
 
         var visualizers = dataSource._visualizers;
         var length = visualizers.length;
@@ -336,9 +393,36 @@ define([
             visualizers[i].destroy();
         }
 
+        displayPrimitives.remove(primitives);
+        displayGroundPrimitives.remove(groundPrimitives);
+
         dataSource._visualizers = undefined;
     };
 
+    DataSourceDisplay.prototype._onDataSourceMoved = function(dataSource, newIndex, oldIndex) {
+        var displayPrimitives = this._primitives;
+        var displayGroundPrimitives = this._groundPrimitives;
+
+        var primitives = dataSource._primitives;
+        var groundPrimitives = dataSource._groundPrimitives;
+
+        if (newIndex === oldIndex + 1) {
+            displayPrimitives.raise(primitives);
+            displayGroundPrimitives.raise(groundPrimitives);
+        } else if (newIndex === oldIndex - 1) {
+            displayPrimitives.lower(primitives);
+            displayGroundPrimitives.lower(groundPrimitives);
+        } else if (newIndex === 0) {
+            displayPrimitives.lowerToBottom(primitives);
+            displayGroundPrimitives.lowerToBottom(groundPrimitives);
+            displayPrimitives.raise(primitives); // keep defaultDataSource primitives at index 0 since it's not in the collection
+            displayGroundPrimitives.raise(groundPrimitives);
+        } else {
+            displayPrimitives.raiseToTop(primitives);
+            displayGroundPrimitives.raiseToTop(groundPrimitives);
+        }
+    };
+
     /**
      * A function which creates an array of visualizers used for visualization.
      * @callback DataSourceDisplay~VisualizersCallback
diff --git a/Source/DataSources/GeometryVisualizer.js b/Source/DataSources/GeometryVisualizer.js
index 706d46ce814f..72ed71a89100 100644
--- a/Source/DataSources/GeometryVisualizer.js
+++ b/Source/DataSources/GeometryVisualizer.js
@@ -2,6 +2,7 @@ define([
         '../Core/AssociativeArray',
         '../Core/BoundingSphere',
         '../Core/Check',
+        '../Core/defaultValue',
         '../Core/defined',
         '../Core/destroyObject',
         '../Core/DeveloperError',
@@ -32,6 +33,7 @@ define([
         AssociativeArray,
         BoundingSphere,
         Check,
+        defaultValue,
         defined,
         destroyObject,
         DeveloperError,
@@ -117,15 +119,18 @@ define([
      *
      * @param {Scene} scene The scene the primitives will be rendered in.
      * @param {EntityCollection} entityCollection The entityCollection to visualize.
+     * @param {PrimitiveCollection} [primitives=scene.primitives] A collection to add primitives related to the entities
+     * @param {PrimitiveCollection} [groundPrimitives=scene.groundPrimitives] A collection to add ground primitives related to the entities
      */
-    function GeometryVisualizer(scene, entityCollection) {
+    function GeometryVisualizer(scene, entityCollection, primitives, groundPrimitives) {
         //>>includeStart('debug', pragmas.debug);
         Check.defined('scene', scene);
         Check.defined('entityCollection', entityCollection);
         //>>includeEnd('debug');
 
-        var primitives = scene.primitives;
-        var groundPrimitives = scene.groundPrimitives;
+        primitives = defaultValue(primitives, scene.primitives);
+        groundPrimitives = defaultValue(groundPrimitives, scene.groundPrimitives);
+
         this._scene = scene;
         this._primitives = primitives;
         this._groundPrimitives = groundPrimitives;
diff --git a/Specs/DataSources/DataSourceCollectionSpec.js b/Specs/DataSources/DataSourceCollectionSpec.js
index 874aed160f69..43a30aecd973 100644
--- a/Specs/DataSources/DataSourceCollectionSpec.js
+++ b/Specs/DataSources/DataSourceCollectionSpec.js
@@ -53,6 +53,37 @@ defineSuite([
         expect(removeSpy).toHaveBeenCalledWith(collection, source);
     });
 
+    it('move event works', function() {
+        var source = new MockDataSource();
+        var collection = new DataSourceCollection();
+        collection.add(source);
+
+        var moveSpy = jasmine.createSpy('dataSourceMoved');
+        collection.dataSourceMoved.addEventListener(moveSpy);
+
+        collection.raise(source);
+        collection.lower(source);
+        collection.raiseToTop(source);
+        collection.lowerToBottom(source);
+
+        expect(moveSpy).not.toHaveBeenCalled();
+
+        collection.add(new MockDataSource());
+        collection.add(new MockDataSource());
+
+        collection.raise(source);
+        expect(moveSpy).toHaveBeenCalledWith(source, 1, 0);
+
+        collection.lower(source);
+        expect(moveSpy).toHaveBeenCalledWith(source, 0, 1);
+
+        collection.raiseToTop(source);
+        expect(moveSpy).toHaveBeenCalledWith(source, 2, 0);
+
+        collection.lowerToBottom(source);
+        expect(moveSpy).toHaveBeenCalledWith(source, 0, 2);
+    });
+
     it('add works with promise', function() {
         var promise = when.defer();
         var source = new MockDataSource();
diff --git a/Specs/DataSources/DataSourceDisplaySpec.js b/Specs/DataSources/DataSourceDisplaySpec.js
index 6c243b072063..ed0199b589ac 100644
--- a/Specs/DataSources/DataSourceDisplaySpec.js
+++ b/Specs/DataSources/DataSourceDisplaySpec.js
@@ -45,6 +45,7 @@ defineSuite([
         if (!display.isDestroyed()) {
             display.destroy();
         }
+        dataSourceCollection.removeAll();
     });
 
     function MockVisualizer() {
@@ -377,4 +378,172 @@ defineSuite([
             expect(display.ready).toBe(true);
         });
     });
+
+    it('sets dataSource primitives on add', function() {
+        var source = new MockDataSource();
+
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        dataSourceCollection.add(source);
+
+        expect(source._primitives).toBeDefined();
+        expect(source._groundPrimitives).toBeDefined();
+
+        expect(display._primitives.contains(source._primitives)).toBe(true);
+        expect(display._groundPrimitives.contains(source._groundPrimitives)).toBe(true);
+    });
+
+    it('cleans up primitives on dataSource removed', function() {
+        var source = new MockDataSource();
+
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        dataSourceCollection.add(source);
+
+        expect(display._primitives.contains(source._primitives)).toBe(true);
+        expect(display._groundPrimitives.contains(source._groundPrimitives)).toBe(true);
+
+        dataSourceCollection.remove(source);
+
+        expect(display._primitives.length).toBe(1);
+        expect(display._groundPrimitives.length).toBe(1);
+    });
+
+    it('raises primitives on dataSource raise', function() {
+        var source1 = new MockDataSource();
+        var source2 = new MockDataSource();
+        var source3 = new MockDataSource();
+
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        dataSourceCollection.add(source1);
+        dataSourceCollection.add(source2);
+        dataSourceCollection.add(source3);
+
+        dataSourceCollection.raise(source1);
+
+        expect(display._primitives.get(1)).toBe(source2._primitives);
+        expect(display._primitives.get(2)).toBe(source1._primitives);
+        expect(display._primitives.get(3)).toBe(source3._primitives);
+    });
+
+    it('lowers primitives on dataSource lower', function() {
+        var source1 = new MockDataSource();
+        var source2 = new MockDataSource();
+        var source3 = new MockDataSource();
+
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        dataSourceCollection.add(source1);
+        dataSourceCollection.add(source2);
+        dataSourceCollection.add(source3);
+
+        dataSourceCollection.lower(source3);
+
+        expect(display._primitives.get(1)).toBe(source1._primitives);
+        expect(display._primitives.get(2)).toBe(source3._primitives);
+        expect(display._primitives.get(3)).toBe(source2._primitives);
+    });
+
+    it('raises primitives to top on dataSource raiseToTop', function() {
+        var source1 = new MockDataSource();
+        var source2 = new MockDataSource();
+        var source3 = new MockDataSource();
+
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        dataSourceCollection.add(source1);
+        dataSourceCollection.add(source2);
+        dataSourceCollection.add(source3);
+
+        dataSourceCollection.raiseToTop(source1);
+
+        expect(display._primitives.get(1)).toBe(source2._primitives);
+        expect(display._primitives.get(2)).toBe(source3._primitives);
+        expect(display._primitives.get(3)).toBe(source1._primitives);
+    });
+
+    it('lowers primitives to bottom on dataSource lowerToBottom', function() {
+        var source1 = new MockDataSource();
+        var source2 = new MockDataSource();
+        var source3 = new MockDataSource();
+
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        dataSourceCollection.add(source1);
+        dataSourceCollection.add(source2);
+        dataSourceCollection.add(source3);
+
+        dataSourceCollection.lowerToBottom(source3);
+
+        expect(display._primitives.get(1)).toBe(source3._primitives);
+        expect(display._primitives.get(2)).toBe(source1._primitives);
+        expect(display._primitives.get(3)).toBe(source2._primitives);
+    });
+
+    it('adds primitives to scene when dataSource is added to the collection', function() {
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+        expect(scene.primitives.contains(display._primitives)).toBe(false);
+        expect(scene.groundPrimitives.contains(display._groundPrimitives)).toBe(false);
+
+        dataSourceCollection.add(new MockDataSource());
+
+        expect(scene.primitives.contains(display._primitives)).toBe(true);
+        expect(scene.groundPrimitives.contains(display._groundPrimitives)).toBe(true);
+    });
+
+    it('adds primitives to scene if dataSourceCollection is not empty', function() {
+        dataSourceCollection.add(new MockDataSource());
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+
+        expect(scene.primitives.contains(display._primitives)).toBe(true);
+        expect(scene.groundPrimitives.contains(display._groundPrimitives)).toBe(true);
+    });
+
+    it('adds primitives to the scene when entities are added to the default dataSource', function() {
+        display = new DataSourceDisplay({
+            scene : scene,
+            dataSourceCollection : dataSourceCollection,
+            visualizersCallback : visualizersCallback
+        });
+        expect(scene.primitives.contains(display._primitives)).toBe(false);
+        expect(scene.groundPrimitives.contains(display._groundPrimitives)).toBe(false);
+
+        display.defaultDataSource.entities.add(new Entity());
+
+        expect(scene.primitives.contains(display._primitives)).toBe(true);
+        expect(scene.groundPrimitives.contains(display._groundPrimitives)).toBe(true);
+    });
 }, 'WebGL');
diff --git a/Specs/DataSources/GeometryVisualizerSpec.js b/Specs/DataSources/GeometryVisualizerSpec.js
index 6ed873b66239..689ea3df8aa8 100644
--- a/Specs/DataSources/GeometryVisualizerSpec.js
+++ b/Specs/DataSources/GeometryVisualizerSpec.js
@@ -82,7 +82,7 @@ defineSuite([
 
     it('Can create and destroy', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
         expect(visualizer.update(time)).toBe(true);
         expect(scene.primitives.length).toBe(0);
         expect(visualizer.isDestroyed()).toBe(false);
@@ -92,7 +92,7 @@ defineSuite([
 
     it('Creates and removes static color open geometry', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -134,7 +134,7 @@ defineSuite([
 
     it('Creates and removes static material open geometry', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -175,7 +175,7 @@ defineSuite([
 
     it('Creates and removes static color closed geometry', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -217,7 +217,7 @@ defineSuite([
 
     it('Creates and removes static material closed geometry', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -259,7 +259,7 @@ defineSuite([
 
     it('Creates and removes static outline geometry', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -301,7 +301,7 @@ defineSuite([
 
     function createAndRemoveGeometryWithShadows(shadows) {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -355,7 +355,7 @@ defineSuite([
 
     function createAndRemoveGeometryWithClassificationType(type) {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -404,7 +404,7 @@ defineSuite([
 
     it('Correctly handles geometry changing batches', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -459,7 +459,7 @@ defineSuite([
 
     it('Correctly handles modifying translucent outline color', function() {
         var entities = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entities);
+        var visualizer = new GeometryVisualizer(scene, entities, scene.primitives, scene.groundPrimitives);
 
         var color = Color.BLUE.withAlpha(0.5);
         var entity = entities.add({
@@ -506,7 +506,7 @@ defineSuite([
 
     it('Creates and removes dynamic geometry', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new SampledProperty(Number);
@@ -533,7 +533,7 @@ defineSuite([
 
     it('Creates and removes dynamic geometry on terrain ', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new SampledProperty(Number);
@@ -557,22 +557,21 @@ defineSuite([
         visualizer.destroy();
     });
 
-    it('Constructor throws without type', function() {
+    it('Constructor throws without scene', function() {
         var objects = new EntityCollection();
         expect(function() {
-            return new GeometryVisualizer(undefined, scene, objects);
+            return new GeometryVisualizer(undefined, objects, scene.primitives, scene.groundPrimitives);
         }).toThrowDeveloperError();
     });
 
-    it('Constructor throws without scene', function() {
-        var objects = new EntityCollection();
+    it('Constructor throws without entityCollection', function() {
         expect(function() {
-            return new GeometryVisualizer(undefined, objects);
+            return new GeometryVisualizer(scene, undefined, scene.primitives, scene.groundPrimitives);
         }).toThrowDeveloperError();
     });
 
     it('Update throws without time parameter', function() {
-        var visualizer = new GeometryVisualizer(scene, new EntityCollection());
+        var visualizer = new GeometryVisualizer(scene, new EntityCollection(), scene.primitives, scene.groundPrimitives);
         expect(function() {
             visualizer.update(undefined);
         }).toThrowDeveloperError();
@@ -580,7 +579,7 @@ defineSuite([
 
     it('removes the listener from the entity collection when destroyed', function() {
         var entityCollection = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entityCollection);
+        var visualizer = new GeometryVisualizer(scene, entityCollection, scene.primitives, scene.groundPrimitives);
         expect(entityCollection.collectionChanged.numberOfListeners).toEqual(1);
         visualizer.destroy();
         expect(entityCollection.collectionChanged.numberOfListeners).toEqual(0);
@@ -588,7 +587,7 @@ defineSuite([
 
     it('Computes dynamic geometry bounding sphere.', function() {
         var entityCollection = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entityCollection);
+        var visualizer = new GeometryVisualizer(scene, entityCollection, scene.primitives, scene.groundPrimitives);
 
         var ellipse = new EllipseGraphics();
         ellipse.semiMajorAxis = new ConstantProperty(2);
@@ -621,7 +620,7 @@ defineSuite([
 
     it('Compute dynamic geometry bounding sphere throws without entity.', function() {
         var entityCollection = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entityCollection);
+        var visualizer = new GeometryVisualizer(scene, entityCollection, scene.primitives, scene.groundPrimitives);
 
         var result = new BoundingSphere();
         expect(function() {
@@ -635,7 +634,7 @@ defineSuite([
         var entityCollection = new EntityCollection();
         var entity = new Entity();
         entityCollection.add(entity);
-        var visualizer = new GeometryVisualizer(scene, entityCollection);
+        var visualizer = new GeometryVisualizer(scene, entityCollection, scene.primitives, scene.groundPrimitives);
 
         expect(function() {
             visualizer.getBoundingSphere(entity, undefined);
@@ -646,7 +645,7 @@ defineSuite([
 
     it('Can remove and entity and then add a new new instance with the same id.', function() {
         var objects = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, objects);
+        var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives);
 
         var entity = new Entity({
             id : 'test',
@@ -710,7 +709,7 @@ defineSuite([
 
     it('Sets static geometry primitive show attribute when using dynamic fill color', function() {
         var entities = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entities);
+        var visualizer = new GeometryVisualizer(scene, entities, scene.primitives, scene.groundPrimitives);
 
         var entity = entities.add({
             position : new Cartesian3(1234, 5678, 9101112),
@@ -754,7 +753,7 @@ defineSuite([
 
     it('Sets static geometry primitive show attribute when using dynamic outline color', function() {
         var entities = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entities);
+        var visualizer = new GeometryVisualizer(scene, entities, scene.primitives, scene.groundPrimitives);
 
         var entity = entities.add({
             position : new Cartesian3(1234, 5678, 9101112),
@@ -799,7 +798,7 @@ defineSuite([
 
     it('Sets static geometry primitive show attribute when using dynamic fill material', function() {
         var entities = new EntityCollection();
-        var visualizer = new GeometryVisualizer(scene, entities);
+        var visualizer = new GeometryVisualizer(scene, entities, scene.primitives, scene.groundPrimitives);
 
         var entity = entities.add({
             position : new Cartesian3(1234, 5678, 9101112),