diff --git a/lib/types/array.js b/lib/types/array.js
index 3d4abf600b9..78960e879e5 100644
--- a/lib/types/array.js
+++ b/lib/types/array.js
@@ -72,11 +72,20 @@ MongooseArray.prototype._parent;
  */
 
 MongooseArray.prototype._cast = function (value) {
-  var cast = this._schema.caster.cast
-    , doc = this._parent;
+  var populated = false;
+  var owner;
+
+  if (this._parent && value instanceof Document) {
+    owner = this._parent.ownerDocument
+      ? this._parent.ownerDocument()
+      : this._parent;
+    if (owner.populated(this._path)) {
+      populated = true;
+    }
+  }
 
-  return cast.call(null, value, doc);
-};
+  return this._schema.caster.cast(value, this._parent, populated)
+}
 
 /**
  * Marks this array as modified.
@@ -103,7 +112,6 @@ MongooseArray.prototype._markModified = function (elem, embeddedPath) {
         // directly set an index
         dirtyPath = dirtyPath + '.' + elem;
       }
-
     }
     parent.markModified(dirtyPath);
   }
diff --git a/test/model.populate.test.js b/test/model.populate.test.js
index 2643932b6cf..dba9471db7e 100644
--- a/test/model.populate.test.js
+++ b/test/model.populate.test.js
@@ -2005,5 +2005,94 @@ describe('model: populate:', function(){
     })
   })
 
+  describe('setting populated paths (gh-570)', function(){
+    var db;
+    var B;
+    var U;
+    var u1, u2;
+    var b1, b2
+
+    before(function(done){
+      db = start()
+      B = db.model('RefBlogPost', posts + random())
+      U = db.model('RefUser', users + random());
+
+      U.create({
+          name  : 'Fan 1'
+        , email : 'fan1@learnboost.com'
+      }, {
+          name  : 'Fan 2'
+        , email : 'fan2@learnboost.com'
+      }, function (err, fan1, fan2) {
+        assert.ifError(err);
+        u1 = fan1;
+        u2 = fan2;
+
+        B.create({
+            title : 'Woot'
+          , fans  : [fan1, fan2]
+          , _creator: fan1
+        }, {
+            title : 'Woot2'
+          , fans  : [fan2, fan1]
+          , _creator: fan2
+        }, function (err, post1, post2) {
+          assert.ifError(err);
+          b1 = post1;
+          b2 = post2;
+          done();
+        });
+      });
+    })
+
+    after(function(){
+      db.close()
+    })
+
+    describe('should not cast to _id', function(){
+      it('if a document', function(done){
+        B.findById(b1).populate('fans _creator').exec(function (err, doc) {
+          assert.ifError(err);
 
+          var user3 = new U({ name: 'user3' });
+          doc.fans.push(user3);
+          assert.equal(doc.fans[2], user3);
+
+          var user4 = new U({ name: 'user4' });
+          doc.fans.nonAtomicPush(user4);
+          assert.equal(doc.fans[3], user4);
+
+          var user5 = new U({ name: 'user5' });
+          doc.fans.splice(2, 1, user5);
+          assert.equal(doc.fans[2], user5);
+
+          var user6 = new U({ name: 'user6' });
+          doc.fans.unshift(user6);
+          assert.equal(doc.fans[0], user6);
+
+          var user7 = new U({ name: 'user7' });
+          doc.fans.addToSet(user7);
+          assert.equal(doc.fans[5], user7);
+
+          doc.fans.forEach(function (doc) {
+            assert.ok(doc instanceof U);
+          })
+
+          var user8 = new U({ name: 'user8' });
+          doc.fans.set(0, user8);
+          assert.equal(doc.fans[0], user8);
+
+          doc.fans.push(null);
+          assert.equal(doc.fans[6], null);
+
+          var _id = new DocObjectId;
+          doc.fans.addToSet(_id);
+          assert.equal(doc.fans[7], _id);
+
+          done();
+        })
+        // TODO test with Buffer, Number, String _ids too
+      })
+    })
+  })
 });