diff --git a/extern/carve/carve-capi.cc b/extern/carve/carve-capi.cc
index a65d1a8d76696359d5878e3ef430a83dc87a44ff..af9ecad685d6e997f49d9c580b47223490fa441c 100644
--- a/extern/carve/carve-capi.cc
+++ b/extern/carve/carve-capi.cc
@@ -38,7 +38,7 @@ typedef std::pair<int, int> OrigIndex;
 typedef std::pair<MeshSet<3>::vertex_t *, MeshSet<3>::vertex_t *> VertexPair;
 typedef carve::interpolate::VertexAttr<OrigIndex> OrigVertMapping;
 typedef carve::interpolate::FaceAttr<OrigIndex> OrigFaceMapping;
-typedef carve::interpolate::FaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
+typedef carve::interpolate::SwapableFaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
 typedef carve::interpolate::SimpleFaceEdgeAttr<bool> FaceEdgeTriangulatedFlag;
 
 typedef struct CarveMeshDescr {
@@ -522,6 +522,39 @@ public:
 	}
 };
 
+template <typename Interpolator>
+void copyFaceEdgeAttrs(const MeshSet<3> *poly,
+                       Interpolator *old_interpolator,
+                       Interpolator *new_interpolator)
+{
+	for (MeshSet<3>::const_face_iter face_iter = poly->faceBegin();
+	     face_iter != poly->faceEnd();
+	     ++face_iter)
+	{
+		const MeshSet<3>::face_t *face = *face_iter;
+
+		for (int edge_index = 0;
+		     edge_index < face->nEdges();
+		     ++edge_index)
+		{
+			new_interpolator->copyAttribute(face,
+			                                edge_index,
+			                                old_interpolator);
+		}
+	}
+}
+
+template <typename Interpolator>
+void cleanupFaceEdgeAttrs(const MeshSet<3> *left,
+                          const MeshSet<3> *right,
+                          Interpolator *interpolator)
+{
+	Interpolator new_interpolator;
+	copyFaceEdgeAttrs(left, interpolator, &new_interpolator);
+	copyFaceEdgeAttrs(right, interpolator, &new_interpolator);
+	interpolator->swapAttributes(&new_interpolator);
+}
+
 }  // namespace
 
 CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
@@ -698,7 +731,15 @@ bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
 		// intersecting that meshes tessellation of operation result can't be
 		// done properly. The only way to make such situations working is to
 		// union intersecting meshes of the same operand.
-		carve_unionIntersections(&csg, &left, &right);
+		if (carve_unionIntersections(&csg, &left, &right)) {
+			cleanupFaceEdgeAttrs(left,
+			                     right,
+			                     &output_descr->face_edge_triangulated_flag);
+			cleanupFaceEdgeAttrs(left,
+			                     right,
+			                     &output_descr->orig_face_edge_mapping);
+		}
+
 		left_mesh->poly = left;
 		right_mesh->poly = right;
 
diff --git a/extern/carve/carve-util.cc b/extern/carve/carve-util.cc
index ac6dcbc1a941181e43eac338cdd8a9c1bd0843cb..b268dae9dd6f8564898d0ba1417ad3d3b13e901f 100644
--- a/extern/carve/carve-util.cc
+++ b/extern/carve/carve-util.cc
@@ -486,14 +486,15 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
 
 // TODO(sergey): This function is to be totally re-implemented to make it
 // more clear what's going on and hopefully optimize it as well.
-void carve_unionIntersections(carve::csg::CSG *csg,
+bool carve_unionIntersections(carve::csg::CSG *csg,
                               MeshSet<3> **left_r,
                               MeshSet<3> **right_r)
 {
 	MeshSet<3> *left = *left_r, *right = *right_r;
+	bool changed = false;
 
 	if (left->meshes.size() == 1 && right->meshes.size() == 0) {
-		return;
+		return false;
 	}
 
 	MeshSet<3>::aabb_t leftAABB = left->getAABB();
@@ -503,14 +504,19 @@ void carve_unionIntersections(carve::csg::CSG *csg,
 	right = unionIntersectingMeshes(csg, right, leftAABB);
 
 	if (left != *left_r) {
+		changed = true;
 		delete *left_r;
 	}
 
-	if (right != *right_r)
+	if (right != *right_r) {
+		changed = true;
 		delete *right_r;
+	}
 
 	*left_r = left;
 	*right_r = right;
+
+	return changed;
 }
 
 static inline void add_newell_cross_v3_v3v3(const Vector &v_prev,
diff --git a/extern/carve/carve-util.h b/extern/carve/carve-util.h
index a658b2fea962d7c3377cf024f76bcfbf21d1fad0..f650810e9e335a02793b98b5d3a2a104b0dd52eb 100644
--- a/extern/carve/carve-util.h
+++ b/extern/carve/carve-util.h
@@ -70,7 +70,7 @@ void carve_getRescaleMinMax(const carve::mesh::MeshSet<3> *left,
                             carve::geom3d::Vector *min,
                             carve::geom3d::Vector *max);
 
-void carve_unionIntersections(carve::csg::CSG *csg,
+bool carve_unionIntersections(carve::csg::CSG *csg,
                               carve::mesh::MeshSet<3> **left_r,
                               carve::mesh::MeshSet<3> **right_r);
 
@@ -115,8 +115,8 @@ namespace carve {
 						attrs.find(new_edge_iter->vert);
 					if (found == attrs.end()) {
 						for (const_edge_iter_t orig_edge_iter = orig_face->begin();
-							 orig_edge_iter != orig_face->end();
-							 ++orig_edge_iter)
+						     orig_edge_iter != orig_face->end();
+						     ++orig_edge_iter)
 						{
 							if ((orig_edge_iter->vert->v - new_edge_iter->vert->v).length2() < 1e-5) {
 								attrs[new_edge_iter->vert] = attrs[orig_edge_iter->vert];
@@ -236,6 +236,20 @@ namespace carve {
 				attrs[std::make_pair(f, e)] = attr;
 			}
 
+			void copyAttribute(const meshset_t::face_t *face,
+			                   unsigned edge,
+			                   SimpleFaceEdgeAttr<attr_t> *interpolator) {
+				key_t key(face, edge);
+				typename attrmap_t::const_iterator fv = interpolator->attrs.find(key);
+				if (fv != interpolator->attrs.end()) {
+					attrs[key] = (*fv).second;
+				}
+			}
+
+			void swapAttributes(SimpleFaceEdgeAttr<attr_t> *interpolator) {
+				attrs.swap(interpolator->attrs);
+			}
+
 			SimpleFaceEdgeAttr() : Interpolator() {
 			}
 
@@ -243,6 +257,25 @@ namespace carve {
 			}
 		};
 
+		template<typename attr_t>
+		class SwapableFaceEdgeAttr : public FaceEdgeAttr<attr_t> {
+		public:
+			typedef carve::mesh::MeshSet<3> meshset_t;
+
+			void copyAttribute(const meshset_t::face_t *face,
+			                   unsigned edge,
+			                   SwapableFaceEdgeAttr<attr_t> *interpolator) {
+				typename FaceEdgeAttr<attr_t>::key_t key(face, edge);
+				typename FaceEdgeAttr<attr_t>::attrmap_t::const_iterator fv = interpolator->attrs.find(key);
+				if (fv != interpolator->attrs.end()) {
+					this->attrs[key] = (*fv).second;
+				}
+			}
+
+			void swapAttributes(SwapableFaceEdgeAttr<attr_t> *interpolator) {
+				this->attrs.swap(interpolator->attrs);
+			}
+		};
 	}  // namespace interpolate
 }  // namespace carve
 
diff --git a/extern/carve/include/carve/config.h b/extern/carve/include/carve/config.h
index fdae2d2843f142a6b9d01b152366cc1247926e3e..3533c1a67107b84d828303f2e196af394b48b42a 100644
--- a/extern/carve/include/carve/config.h
+++ b/extern/carve/include/carve/config.h
@@ -10,3 +10,21 @@
 
 #  define HAVE_STDINT_H
 #endif
+
+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
+//
+// TODO(sergey): Move it some some more generic header with platform-specific
+//               declarations.
+
+// Indicates whether __is_heap is available
+#undef HAVE_IS_HEAP
+
+#ifdef __GNUC__
+// NeyBSD doesn't have __is_heap
+#  ifndef __NetBSD__
+#    define HAVE_IS_HEAP
+#    ifdef _LIBCPP_VERSION
+#      define __is_heap is_heap
+#    endif  // _LIBCPP_VERSION
+#  endif  // !__NetBSD__
+#endif  // __GNUC__
diff --git a/extern/carve/include/carve/mesh_ops.hpp b/extern/carve/include/carve/mesh_ops.hpp
index 02b1bde4e45203b08494063d80a32ab82d57a607..3b71feb0e6c6f859c3d1cc83406afc043571c05d 100644
--- a/extern/carve/include/carve/mesh_ops.hpp
+++ b/extern/carve/include/carve/mesh_ops.hpp
@@ -580,7 +580,7 @@ namespace carve {
           std::vector<VertexInfo *> queue;
 
           void checkheap() {
-#ifdef __GNUC__
+#if defined(HAVE_IS_HEAP)
             CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
 #endif
           }
diff --git a/extern/carve/lib/triangulator.cpp b/extern/carve/lib/triangulator.cpp
index 820fed07db7db6d88a801a4dea4af4e61a9aff9e..eb36e86af5d5ca907e03c4f6071e2c914191b7bc 100644
--- a/extern/carve/lib/triangulator.cpp
+++ b/extern/carve/lib/triangulator.cpp
@@ -27,24 +27,6 @@
 
 #include <algorithm>
 
-// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
-//
-// TODO(sergey): Move it some some more generic header with platform-specific
-//               declarations.
-
-// Indicates whether __is_heap is available
-#undef HAVE_IS_HEAP
-
-#ifdef __GNUC__
-// NeyBSD doesn't have __is_heap
-#  ifndef __NetBSD__
-#    define HAVE_IS_HEAP
-#    ifdef _LIBCPP_VERSION
-#      define __is_heap is_heap
-#    endif  // _LIBCPP_VERSION
-#  endif  // !__NetBSD__
-#endif  // __GNUC__
-
 namespace {
   // private code related to hole patching.
 
diff --git a/extern/carve/patches/clang_is_heap_fix.patch b/extern/carve/patches/clang_is_heap_fix.patch
index a00710b95400dddf4328e0cb709345e25cd1ce86..524a8e0420c94e4da0294929c8df279013d15bf5 100644
--- a/extern/carve/patches/clang_is_heap_fix.patch
+++ b/extern/carve/patches/clang_is_heap_fix.patch
@@ -1,31 +1,27 @@
-diff -r 2e6e59022e6e lib/triangulator.cpp
---- a/lib/triangulator.cpp	Fri Nov 09 09:35:35 2012 +1100
-+++ b/lib/triangulator.cpp	Thu Jan 09 16:13:17 2014 +0600
-@@ -27,6 +27,23 @@
+diff -r e82d852e4fb0 include/carve/mesh_ops.hpp
+--- a/include/carve/mesh_ops.hpp	Wed Jan 15 13:16:14 2014 +1100
++++ b/include/carve/mesh_ops.hpp	Fri Mar 28 14:34:04 2014 +0600
+@@ -580,7 +580,7 @@
+           std::vector<VertexInfo *> queue;
  
- #include <algorithm>
+           void checkheap() {
+-#ifdef __GNUC__
++#if defined(HAVE_IS_HEAP)
+             CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
+ #endif
+           }
+diff -r e82d852e4fb0 lib/triangulator.cpp
+--- a/lib/triangulator.cpp	Wed Jan 15 13:16:14 2014 +1100
++++ b/lib/triangulator.cpp	Fri Mar 28 14:34:04 2014 +0600
+@@ -27,7 +27,6 @@
  
-+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
-+//
-+// TODO(sergey): Move it some some more generic header with platform-specific
-+//               declarations.
-+
-+// Indicates whether __is_heap is available
-+#undef HAVE_IS_HEAP
-+
-+#ifdef __GNUC__
-+// NeyBSD doesn't have __is_heap
-+#  ifndef __NetBSD__
-+#    define HAVE_IS_HEAP
-+#    ifdef _LIBCPP_VERSION
-+#      define __is_heap is_heap
-+#    endif  // _LIBCPP_VERSION
-+#  endif  // !__NetBSD__
-+#endif  // __GNUC__
+ #include <algorithm>
  
+-
  namespace {
    // private code related to hole patching.
-@@ -122,7 +139,7 @@
+ 
+@@ -122,7 +121,7 @@
      std::vector<vertex_info *> queue;
  
      void checkheap() {
diff --git a/extern/carve/patches/files/config.h b/extern/carve/patches/files/config.h
index fdae2d2843f142a6b9d01b152366cc1247926e3e..3533c1a67107b84d828303f2e196af394b48b42a 100644
--- a/extern/carve/patches/files/config.h
+++ b/extern/carve/patches/files/config.h
@@ -10,3 +10,21 @@
 
 #  define HAVE_STDINT_H
 #endif
+
+// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
+//
+// TODO(sergey): Move it some some more generic header with platform-specific
+//               declarations.
+
+// Indicates whether __is_heap is available
+#undef HAVE_IS_HEAP
+
+#ifdef __GNUC__
+// NeyBSD doesn't have __is_heap
+#  ifndef __NetBSD__
+#    define HAVE_IS_HEAP
+#    ifdef _LIBCPP_VERSION
+#      define __is_heap is_heap
+#    endif  // _LIBCPP_VERSION
+#  endif  // !__NetBSD__
+#endif  // __GNUC__
diff --git a/extern/carve/patches/series b/extern/carve/patches/series
index 286d594bbef7f93eb727fec0eec6b1c9e2821b3c..529bf43a8588720c1e73f12f766954e717fd8b6a 100644
--- a/extern/carve/patches/series
+++ b/extern/carve/patches/series
@@ -8,5 +8,5 @@ strict_flags.patch
 interpolator_reorder.patch
 mesh_simplify_dissolve_edges.patch
 memory_leak_fix.patch
-mavc_fix.patch
+msvc_fix.patch
 face_hole_merge_workaround.patch
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
index 641d2518fb85e5ea5c01367f2f5d37605ebcf673..2e8e99af0eb4e3b55c623d626ea3e125aa72a8c6 100644
--- a/extern/libmv/ChangeLog
+++ b/extern/libmv/ChangeLog
@@ -1,3 +1,11 @@
+commit 901b146f28825d3e05f4157ca2a34ae00261b91a
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Wed Mar 26 17:44:09 2014 +0600
+
+    Fix bad memory write in BA code when having zero-weighted tracks
+    
+    Issue was really stupid and caused by the wrong vector initialization.
+
 commit b1381540305d69c702eb2f051bd543fb5c1c3e2c
 Author: Sergey Sharybin <sergey.vfx@gmail.com>
 Date:   Thu Feb 6 18:01:58 2014 +0600
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc
index 09523340ed74bc15c9075b5ef4722840a8b1edb9..f571b0fcaab4a958d7124a1ca1c420a480753131 100644
--- a/extern/libmv/libmv/simple_pipeline/bundle.cc
+++ b/extern/libmv/libmv/simple_pipeline/bundle.cc
@@ -416,7 +416,7 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks,
   vector<Marker> markers = tracks.AllMarkers();
 
   // N-th element denotes whether track N is a constant zero-weigthed track.
-  vector<bool> zero_weight_tracks_flags(tracks.MaxTrack(), true);
+  vector<bool> zero_weight_tracks_flags(tracks.MaxTrack() + 1, true);
 
   // Residual blocks with 10 parameters are unwieldly with Ceres, so pack the
   // intrinsics into a single block and rely on local parameterizations to
diff --git a/extern/rangetree/range_tree.hh b/extern/rangetree/range_tree.hh
index a88c70281b68dd26c9fef48ad888919d1259e091..919e0b049330d2ac53d7a0ada3cdda7dd338b32f 100644
--- a/extern/rangetree/range_tree.hh
+++ b/extern/rangetree/range_tree.hh
@@ -79,10 +79,6 @@ struct RangeTree {
 		TreeIter iter = tree.find(Range(t));
 		assert(iter != tree.end());
 		Range cur = *iter;
-		TreeIter prev = iter;
-		TreeIter next = iter;
-		--prev;
-		++next;
 
 		/* Remove the original range (note that this does not
 		   invalidate the prev/next iterators) */
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index fdee92a5eb067da05b112ba101b6256e19c519c0..75ecb78b200876f0f18e99660ddbb65301a39450 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -188,7 +188,9 @@ static void display_info(Progress& progress)
 
 static void display()
 {
-	options.session->draw(session_buffer_params());
+	static DeviceDrawParams draw_params = DeviceDrawParams();
+
+	options.session->draw(session_buffer_params(), draw_params);
 
 	display_info(options.session->progress);
 }
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 2ea0b27dff8a04f319a73ec423e69d21230af659..6ffc8c81ce6ee5a294c8be6cd62be88827e99ebe 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -432,6 +432,11 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
 	/* object loop */
 	BL::Scene::objects_iterator b_ob;
 	BL::Scene b_sce = b_scene;
+	/* modifier result type (not exposed as enum in C++ API)
+	 * 1 : eModifierMode_Realtime
+	 * 2 : eModifierMode_Render
+	 */
+	int dupli_settings = preview ? 1 : 2;
 
 	bool cancel = false;
 
@@ -446,7 +451,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
 
 				if(b_ob->is_duplicator() && !object_render_hide_duplis(*b_ob)) {
 					/* dupli objects */
-					b_ob->dupli_list_create(b_scene, 2);
+					b_ob->dupli_list_create(b_scene, dupli_settings);
 
 					BL::Object::dupli_list_iterator b_dup;
 
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index ef578493901f63337a1b91fad6664f62444f4c0e..09e7472caf2ce9784c286833fa6c2c2a4b45489b 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -592,16 +592,14 @@ bool BlenderSession::draw(int w, int h)
 
 	/* draw */
 	BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+	DeviceDrawParams draw_params;
 
-	if(session->params.display_buffer_linear)
-		b_engine.bind_display_space_shader(b_scene);
-
-	bool draw_ok = !session->draw(buffer_params);
+	if(session->params.display_buffer_linear) {
+		draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene);
+		draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine);
+	}
 
-	if(session->params.display_buffer_linear)
-		b_engine.unbind_display_space_shader();
-	
-	return draw_ok;
+	return !session->draw(buffer_params, draw_params);
 }
 
 void BlenderSession::get_status(string& status, string& substatus)
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index a3264f0c5165736872e9f5f6b17664320bebda08..7fd1b79f6bc043981ab10d98d32fcc59a0f02f6b 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -53,7 +53,8 @@ void Device::pixels_free(device_memory& mem)
 	mem_free(mem);
 }
 
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent,
+	const DeviceDrawParams &draw_params)
 {
 	pixels_copy_from(rgba, y, w, h);
 
@@ -80,6 +81,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
 
 		glEnable(GL_TEXTURE_2D);
 
+		if(draw_params.bind_display_space_shader_cb) {
+			draw_params.bind_display_space_shader_cb();
+		}
+
 		glPushMatrix();
 		glTranslatef(0.0f, (float)dy, 0.0f);
 
@@ -98,6 +103,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
 
 		glPopMatrix();
 
+		if(draw_params.unbind_display_space_shader_cb) {
+			draw_params.unbind_display_space_shader_cb();
+		}
+
 		glBindTexture(GL_TEXTURE_2D, 0);
 		glDisable(GL_TEXTURE_2D);
 		glDeleteTextures(1, &texid);
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index bd309e357881573812220aacc42922ffd755d3c1..fba44485810a72f213e26deb3c612a2ca576bb37 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -69,6 +69,11 @@ public:
 
 /* Device */
 
+struct DeviceDrawParams {
+	boost::function<void(void)> bind_display_space_shader_cb;
+	boost::function<void(void)> unbind_display_space_shader_cb;
+};
+
 class Device {
 protected:
 	Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {}
@@ -121,7 +126,8 @@ public:
 	
 	/* opengl drawing */
 	virtual void draw_pixels(device_memory& mem, int y, int w, int h,
-		int dy, int width, int height, bool transparent);
+		int dy, int width, int height, bool transparent,
+		const DeviceDrawParams &draw_params);
 
 #ifdef WITH_NETWORK
 	/* networking */
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 0fbb48cf43157600459d8d40316e9ae9d13d1d08..029293d2a04f92c285dd37225f1f9a64a674eb98 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -892,7 +892,8 @@ public:
 		}
 	}
 
-	void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent)
+	void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent,
+		const DeviceDrawParams &draw_params)
 	{
 		if(!background) {
 			PixelMem pmem = pixel_mem_map[mem.device_pointer];
@@ -925,6 +926,10 @@ public:
 
 			glColor3f(1.0f, 1.0f, 1.0f);
 
+			if(draw_params.bind_display_space_shader_cb) {
+				draw_params.bind_display_space_shader_cb();
+			}
+
 			glPushMatrix();
 			glTranslatef(0.0f, (float)dy, 0.0f);
 				
@@ -943,6 +948,10 @@ public:
 
 			glPopMatrix();
 
+			if(draw_params.unbind_display_space_shader_cb) {
+				draw_params.unbind_display_space_shader_cb();
+			}
+
 			if(transparent)
 				glDisable(GL_BLEND);
 			
@@ -954,7 +963,7 @@ public:
 			return;
 		}
 
-		Device::draw_pixels(mem, y, w, h, dy, width, height, transparent);
+		Device::draw_pixels(mem, y, w, h, dy, width, height, transparent, draw_params);
 	}
 
 	void thread_run(DeviceTask *task)
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 27b9de0769e5c15bc0d0f0f6e7dfcf92a8841dc4..5cb1069d24406a9cde5ff373f50ed6ea93fcd0f7 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -233,7 +233,8 @@ public:
 		mem.device_pointer = tmp;
 	}
 
-	void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
+	void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent,
+		const DeviceDrawParams &draw_params)
 	{
 		device_ptr tmp = rgba.device_pointer;
 		int i = 0, sub_h = h/devices.size();
@@ -247,7 +248,7 @@ public:
 			/* adjust math for w/width */
 
 			rgba.device_pointer = sub.ptr_map[tmp];
-			sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent);
+			sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent, draw_params);
 			i++;
 		}
 
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index da1b7484b7730ad47537fedfe00646c39f016750..fc65922fc87121645472be15c5528e314ee9d9f7 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -358,14 +358,14 @@ void DisplayBuffer::draw_set(int width, int height)
 	draw_height = height;
 }
 
-void DisplayBuffer::draw(Device *device)
+void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
 {
 	if(draw_width != 0 && draw_height != 0) {
 		glPushMatrix();
 		glTranslatef(params.full_x, params.full_y, 0.0f);
 		device_memory& rgba = rgba_data();
 
-		device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent);
+		device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent, draw_params);
 
 		glPopMatrix();
 	}
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 81eaf41077fddb10f7b36cb9f2079cc10af822be..27ab20bbafddfdaf1c7a588f39505244150ea074 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -31,6 +31,7 @@
 CCL_NAMESPACE_BEGIN
 
 class Device;
+struct DeviceDrawParams;
 struct float4;
 
 /* Buffer Parameters
@@ -114,7 +115,7 @@ public:
 	void write(Device *device, const string& filename);
 
 	void draw_set(int width, int height);
-	void draw(Device *device);
+	void draw(Device *device, const DeviceDrawParams& draw_params);
 	bool draw_ready();
 
 	device_memory& rgba_data();
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 0805a6854675559b53d6fa783385b9dda9d810e5..2b799972a97a074c50b55f249f72662b8d345c3f 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -151,7 +151,7 @@ void Session::reset_gpu(BufferParams& buffer_params, int samples)
 	pause_cond.notify_all();
 }
 
-bool Session::draw_gpu(BufferParams& buffer_params)
+bool Session::draw_gpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
 {
 	/* block for buffer access */
 	thread_scoped_lock display_lock(display_mutex);
@@ -170,7 +170,7 @@ bool Session::draw_gpu(BufferParams& buffer_params)
 				gpu_need_tonemap_cond.notify_all();
 			}
 
-			display->draw(device);
+			display->draw(device, draw_params);
 
 			if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
 				return false;
@@ -315,7 +315,7 @@ void Session::reset_cpu(BufferParams& buffer_params, int samples)
 	pause_cond.notify_all();
 }
 
-bool Session::draw_cpu(BufferParams& buffer_params)
+bool Session::draw_cpu(BufferParams& buffer_params, DeviceDrawParams& draw_params)
 {
 	thread_scoped_lock display_lock(display_mutex);
 
@@ -324,7 +324,7 @@ bool Session::draw_cpu(BufferParams& buffer_params)
 		/* then verify the buffers have the expected size, so we don't
 		 * draw previous results in a resized window */
 		if(!buffer_params.modified(display->params)) {
-			display->draw(device);
+			display->draw(device, draw_params);
 
 			if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
 				return false;
@@ -624,12 +624,12 @@ void Session::run()
 		progress.set_update();
 }
 
-bool Session::draw(BufferParams& buffer_params)
+bool Session::draw(BufferParams& buffer_params, DeviceDrawParams &draw_params)
 {
 	if(device_use_gl)
-		return draw_gpu(buffer_params);
+		return draw_gpu(buffer_params, draw_params);
 	else
-		return draw_cpu(buffer_params);
+		return draw_cpu(buffer_params, draw_params);
 }
 
 void Session::reset_(BufferParams& buffer_params, int samples)
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 1227edf81b6f81b9e40785d5033d5adacd8e8ccc..e2a7076f25085eef5d16dd717ba1863767d41910 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -128,7 +128,7 @@ public:
 	~Session();
 
 	void start();
-	bool draw(BufferParams& params);
+	bool draw(BufferParams& params, DeviceDrawParams& draw_params);
 	void wait();
 
 	bool ready_to_reset();
@@ -155,11 +155,11 @@ protected:
 	void reset_(BufferParams& params, int samples);
 
 	void run_cpu();
-	bool draw_cpu(BufferParams& params);
+	bool draw_cpu(BufferParams& params, DeviceDrawParams& draw_params);
 	void reset_cpu(BufferParams& params, int samples);
 
 	void run_gpu();
-	bool draw_gpu(BufferParams& params);
+	bool draw_gpu(BufferParams& params, DeviceDrawParams& draw_params);
 	void reset_gpu(BufferParams& params, int samples);
 
 	bool acquire_tile(Device *tile_device, RenderTile& tile);
diff --git a/release/scripts/addons b/release/scripts/addons
index 6c32300be8cc8d48a3e02055dc43bea2ab98a525..ee2cd7105d505a4f6b4613aba26598f532f97f30 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 6c32300be8cc8d48a3e02055dc43bea2ab98a525
+Subproject commit ee2cd7105d505a4f6b4613aba26598f532f97f30
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 70df5a9df21858c2759b30528d2abed47b96bc4e..1a8bd44e846b6f7f480392f9b5f99c8e7a0c91e8 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -232,17 +232,28 @@ def islandIntersectUvIsland(source, target, SourceOffset):
     return 0 # NO INTERSECTION
 
 
+def rotate_uvs(uv_points, angle):
+
+    if angle != 0.0:
+        mat = Matrix.Rotation(angle, 2)
+        for uv in uv_points:
+            uv[:] = mat * uv
+
+
 def optiRotateUvIsland(faces):
     uv_points = [uv for f in faces  for uv in f.uv]
     angle = geometry.box_fit_2d(uv_points)
 
     if angle != 0.0:
-        mat = Matrix.Rotation(angle, 2)
-        i = 0 # count the serialized uv/vectors
-        for f in faces:
-            for j, k in enumerate(range(i, len(f.v) + i)):
-                f.uv[j][:] = mat * uv_points[k]
-            i += len(f.v)
+        rotate_uvs(uv_points, angle)
+
+    # orient them vertically (could be an option)
+    minx, miny, maxx, maxy = boundsIsland(faces)
+    w, h = maxx - minx, maxy - miny
+    if h < w:
+        from math import pi
+        angle = pi / 2.0
+        rotate_uvs(uv_points, angle)
 
 
 # Takes an island list and tries to find concave, hollow areas to pack smaller islands into.
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index dc01c2c8f3def8e97bc991f361fc0e07d8c0b141..5c8257ca52bc69edc2cc9680589a4e064aa4c4e8 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -123,9 +123,9 @@ class CLIP_HT_header(Header):
         row = layout.row()
         row.template_ID(sc, "clip", open="clip.open")
 
-        layout.prop(sc, "mode", text="")
-
         if clip:
+            layout.prop(sc, "mode", text="")
+
             row = layout.row()
             row.template_ID(sc, "mask", new="mask.new")
 
@@ -1332,17 +1332,6 @@ class CLIP_MT_tracking_specials(Menu):
                         text="Unlock Tracks").action = 'UNLOCK'
 
 
-class CLIP_MT_select_mode(Menu):
-    bl_label = "Select Mode"
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.operator_context = 'INVOKE_REGION_WIN'
-
-        layout.operator_enum("clip.mode_set", "mode")
-
-
 class CLIP_MT_camera_presets(Menu):
     """Predefined tracking camera intrinsics"""
     bl_label = "Camera Presets"
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index fce924484b3de51c008c6b77f0d2f113bec36d22..9bf6aaa17034a4d394f0f7936c271bde294b7f79 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -296,7 +296,7 @@ class IMAGE_MT_uvs(Menu):
         layout.prop(uv, "use_live_unwrap")
         layout.operator("uv.unwrap")
         layout.operator("uv.pin", text="Unpin").clear = True
-        layout.operator("uv.pin")
+        layout.operator("uv.pin").clear = False
 
         layout.separator()
 
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 98c855d9419c0991c9336b151e6b55ebc3b6dda8..5cc3df386b337198c9805b724f13cde2c3b2bb61 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1365,18 +1365,23 @@ class VIEW3D_MT_make_single_user(Menu):
 
         props = layout.operator("object.make_single_user", text="Object")
         props.object = True
+        props.obdata = props.material = props.texture = props.animation = False
 
         props = layout.operator("object.make_single_user", text="Object & Data")
         props.object = props.obdata = True
+        props.material = props.texture = props.animation = False
 
         props = layout.operator("object.make_single_user", text="Object & Data & Materials+Tex")
         props.object = props.obdata = props.material = props.texture = True
+        props.animation = False
 
         props = layout.operator("object.make_single_user", text="Materials+Tex")
         props.material = props.texture = True
+        props.object = props.obdata = props.animation = False
 
         props = layout.operator("object.make_single_user", text="Object Animation")
         props.animation = True
+        props.object = props.obdata = props.material = props.texture = False
 
 
 class VIEW3D_MT_make_links(Menu):
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index ec595320d6aa4854722db44ff1a4cc287ab26a73..c6f6579ec4879519c511c16b4f0c84f6e874ea20 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -49,7 +49,7 @@ extern "C" {
 
 /* used by packaging tools */
 /* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR   
+#define BLENDER_VERSION_CHAR    a
 /* alpha/beta/rc/release, docs use this */
 #define BLENDER_VERSION_CYCLE   release
 
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index a9d5ea7520871dc68b8fe6eb5384321933ac51f6..e85f594daba4fc000c4dcc99c07f0dbbbd67f683 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -144,6 +144,7 @@ void BKE_nurb_knot_calc_v(struct Nurb *nu);
 /* nurb checks if they can be drawn, also clamp order func */
 bool BKE_nurb_check_valid_u(struct Nurb *nu);
 bool BKE_nurb_check_valid_v(struct Nurb *nu);
+bool BKE_nurb_check_valid_uv(struct Nurb *nu);
 
 bool BKE_nurb_order_clamp_u(struct Nurb *nu);
 bool BKE_nurb_order_clamp_v(struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 05bb01a44902266148b3a9160b132fb531fa169e..5652e71420908707dc4d889c161b9df48b52c9e9 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -157,7 +157,7 @@ void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Obje
 /* ************************ DAG querying ********************* */
 
 struct Object *DAG_get_node_object(void *node_v);
-const char *DAG_get_node_name(void *node_v);
+const char *DAG_get_node_name(struct Scene *scene, void *node_v);
 short DAG_get_eval_flags_for_object(struct Scene *scene, void *object);
 bool DAG_is_acyclic(struct Scene *scene);
 
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 5c92cc7b34bfa7dc452d65e90de107b4ad10331e..44a9885cd87912116d4d8c0a271ecd3ea0909f18 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -49,6 +49,7 @@ struct PropertyRNA;
 
 void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void *BKE_libblock_copy_ex(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BKE_libblock_copy_nolib(struct ID *id) ATTR_NONNULL();
 void *BKE_libblock_copy(struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 void  BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
 
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 72c4c21d587d4a2515a3b12413ecc3b104dfae0c..2ad6c54fb6782ab4451aea545e97603f099aefba 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -167,7 +167,8 @@ void BKE_object_tfm_protected_restore(struct Object *ob,
 void BKE_object_handle_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
 void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx,
                                  struct Scene *scene, struct Object *ob,
-                                 struct RigidBodyWorld *rbw);
+                                 struct RigidBodyWorld *rbw,
+                                 const bool do_proxy_update);
 void BKE_object_sculpt_modifiers_changed(struct Object *ob);
 
 int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 0cbb921586867f5122390ed1c19d2db57cdebe48..ea47f0ba47d3f9eff4d0a907bcaa65d6c59288a8 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -99,6 +99,7 @@ typedef struct SeqRenderData {
 	int motion_blur_samples;
 	float motion_blur_shutter;
 	bool skip_cache;
+	bool is_proxy_render;
 } SeqRenderData;
 
 SeqRenderData BKE_sequencer_new_render_data(struct EvaluationContext *eval_ctx, struct Main *bmain,
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index e61d47e87f48fa32c732bfe09bddda6aba78ef6b..0ab633701c1f51bc7a6cc76422362549413d460d 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -129,6 +129,7 @@ typedef struct DagForest {
 	int numNodes;
 	bool is_acyclic;
 	int time;  /* for flushing/tagging, compare with node->lasttime */
+	bool ugly_hack_sorry;  /* prevent type check */
 } DagForest;
 
 // queue operations
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 3088f2ccf9b8682de3f215a251842a83cad305e9..b0c293720c4edaed7c35e8136265fb91446557ac 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -894,7 +894,7 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
 		AnimData *adt = BKE_animdata_from_id(id); \
 		NtId_Type *ntp = (NtId_Type *)id; \
 		if (ntp->nodetree) { \
-			AnimData *adt2 = BKE_animdata_from_id((ID *)ntp); \
+			AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
 			if (adt2) func(id, adt2, user_data); \
 		} \
 		if (adt) func(id, adt, user_data); \
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 1fe01fa963756dbaedf7a19f4e7bb47a26a1c604..cb15b5dbd78c8221c1ab0623c7b21c311acf02eb 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3798,6 +3798,16 @@ bool BKE_nurb_check_valid_v(struct Nurb *nu)
 	return true;
 }
 
+bool BKE_nurb_check_valid_uv(struct Nurb *nu)
+{
+	if (!BKE_nurb_check_valid_u(nu))
+		return false;
+	if ((nu->pntsv > 1) && !BKE_nurb_check_valid_v(nu))
+		return false;
+
+	return true;
+}
+
 bool BKE_nurb_order_clamp_u(struct Nurb *nu)
 {
 	bool changed = false;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index af321302984c800b082338bcb2b5549c6fa2ba99..dc467a5f21552339910b6e4069dbd146a58a2515 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -305,6 +305,7 @@ DagForest *dag_init(void)
 	DagForest *forest;
 	/* use callocN to init all zero */
 	forest = MEM_callocN(sizeof(DagForest), "DAG root");
+	forest->ugly_hack_sorry = true;
 	return forest;
 }
 
@@ -995,7 +996,6 @@ DagNode *dag_find_node(DagForest *forest, void *fob)
 	return NULL;
 }
 
-static int ugly_hack_sorry = 1;         /* prevent type check */
 static int dag_print_dependencies = 0;  /* debugging */
 
 /* no checking of existence, use dag_find_node first or dag_get_node */
@@ -1008,7 +1008,7 @@ DagNode *dag_add_node(DagForest *forest, void *fob)
 		node->ob = fob;
 		node->color = DAG_WHITE;
 
-		if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name);  /* sorry, done for pose sorting */
+		if (forest->ugly_hack_sorry) node->type = GS(((ID *) fob)->name);  /* sorry, done for pose sorting */
 		if (forest->numNodes) {
 			((DagNode *) forest->DagNode.last)->next = node;
 			forest->DagNode.last = node;
@@ -1116,28 +1116,28 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel
 	fob1->child = itA;
 }
 
-static const char *dag_node_name(DagNode *node)
+static const char *dag_node_name(DagForest *dag, DagNode *node)
 {
 	if (node->ob == NULL)
 		return "null";
-	else if (ugly_hack_sorry)
+	else if (dag->ugly_hack_sorry)
 		return ((ID *)(node->ob))->name + 2;
 	else
 		return ((bPoseChannel *)(node->ob))->name;
 }
 
-static void dag_node_print_dependencies(DagNode *node)
+static void dag_node_print_dependencies(DagForest *dag, DagNode *node)
 {
 	DagAdjList *itA;
 
-	printf("%s depends on:\n", dag_node_name(node));
+	printf("%s depends on:\n", dag_node_name(dag, node));
 
 	for (itA = node->parent; itA; itA = itA->next)
-		printf("  %s through %s\n", dag_node_name(itA->node), itA->name);
+		printf("  %s through %s\n", dag_node_name(dag, itA->node), itA->name);
 	printf("\n");
 }
 
-static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
+static int dag_node_print_dependency_recurs(DagForest *dag, DagNode *node, DagNode *endnode)
 {
 	DagAdjList *itA;
 
@@ -1150,8 +1150,8 @@ static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode)
 		return 1;
 
 	for (itA = node->parent; itA; itA = itA->next) {
-		if (dag_node_print_dependency_recurs(itA->node, endnode)) {
-			printf("  %s depends on %s through %s.\n", dag_node_name(node), dag_node_name(itA->node), itA->name);
+		if (dag_node_print_dependency_recurs(dag, itA->node, endnode)) {
+			printf("  %s depends on %s through %s.\n", dag_node_name(dag, node), dag_node_name(dag, itA->node), itA->name);
 			return 1;
 		}
 	}
@@ -1166,8 +1166,8 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode,
 	for (node = dag->DagNode.first; node; node = node->next)
 		node->color = DAG_WHITE;
 
-	printf("  %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name);
-	dag_node_print_dependency_recurs(startnode, endnode);
+	printf("  %s depends on %s through %s.\n", dag_node_name(dag, endnode), dag_node_name(dag, startnode), name);
+	dag_node_print_dependency_recurs(dag, startnode, endnode);
 	printf("\n");
 }
 
@@ -1201,7 +1201,7 @@ static void dag_check_cycle(DagForest *dag)
 	/* debugging print */
 	if (dag_print_dependencies)
 		for (node = dag->DagNode.first; node; node = node->next)
-			dag_node_print_dependencies(node);
+			dag_node_print_dependencies(dag, node);
 
 	/* tag nodes unchecked */
 	for (node = dag->DagNode.first; node; node = node->next)
@@ -2836,7 +2836,7 @@ void DAG_pose_sort(Object *ob)
 	int skip = 0;
 	
 	dag = dag_init();
-	ugly_hack_sorry = 0;  /* no ID structs */
+	dag->ugly_hack_sorry = false;  /* no ID structs */
 
 	rootnode = dag_add_node(dag, NULL);  /* node->ob becomes NULL */
 	
@@ -2963,8 +2963,6 @@ void DAG_pose_sort(Object *ob)
 	
 	free_forest(dag);
 	MEM_freeN(dag);
-	
-	ugly_hack_sorry = 1;
 }
 
 /* ************************  DAG FOR THREADED UPDATE  ********************* */
@@ -3083,14 +3081,14 @@ Object *DAG_get_node_object(void *node_v)
 }
 
 /* Returns node name, used for debug output only, atm. */
-const char *DAG_get_node_name(void *node_v)
+const char *DAG_get_node_name(Scene *scene, void *node_v)
 {
 	DagNode *node = node_v;
 
-	return dag_node_name(node);
+	return dag_node_name(scene->theDag, node);
 }
 
-short DAG_get_eval_flags_for_object(struct Scene *scene, void *object)
+short DAG_get_eval_flags_for_object(Scene *scene, void *object)
 {
 	DagNode *node;
 
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 9582d87c540f2cac4af7aa85fc1352a8b0d6abfc..af3246a1b611667f97826037e961588f90e00830 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1212,7 +1212,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
 		curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution);
 
 	for (nu = nubase.first; nu; nu = nu->next) {
-		if (forRender || nu->hide == 0) {
+		if ((forRender || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
 			int resolu = nu->resolu, resolv = nu->resolv;
 
 			if (renderResolution) {
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index b3e0bfa387b39d26417880294544729cde35f8ef..c2ddd0cac4b0dee43fb5d6118d149c1ab55f492f 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -1744,10 +1744,8 @@ static void statvis_calc_overhang(
 	bool is_max;
 
 	/* fallback */
-	const char col_fallback[2][4] = {
-	    {64, 64, 64, 255},  /* gray */
-	    {0,  0,  0,  255},  /* max color */
-	};
+	unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */
+	unsigned char col_fallback_max[4] = {0,  0,  0,  255}; /* max color */
 
 	BLI_assert(min <= max);
 
@@ -1762,7 +1760,7 @@ static void statvis_calc_overhang(
 	{
 		float fcol[3];
 		weight_to_rgb(fcol, 1.0f);
-		rgb_float_to_uchar((unsigned char *)col_fallback[1], fcol);
+		rgb_float_to_uchar(col_fallback_max, fcol);
 	}
 
 	/* now convert into global space */
@@ -1779,7 +1777,8 @@ static void statvis_calc_overhang(
 			rgb_float_to_uchar(r_face_colors[index], fcol);
 		}
 		else {
-			copy_v4_v4_char((char *)r_face_colors[index], (const char *)(col_fallback[is_max]));
+			unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
+			copy_v4_v4_char((char *)r_face_colors[index], (const char *)fallback);
 		}
 	}
 }
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index b8b126c4c8e86a12443c625f56f4eafa546677da..35751867b1a53392b0e3094f8a640ccc56a6db2c 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -3058,7 +3058,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
 			if (ima->type == IMA_TYPE_MULTILAYER)
 				/* keeps render result, stores ibufs in listbase, allows saving */
 				ibuf = image_get_ibuf_multilayer(ima, iuser);
-
 		}
 		else if (ima->source == IMA_SRC_GENERATED) {
 			/* generated is: ibuf is allocated dynamically */
@@ -3076,9 +3075,6 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
 				/* always verify entirely, and potentially
 				 * returns pointer to release later */
 				ibuf = image_get_render_result(ima, iuser, lock_r);
-				if (ibuf) {
-					ibuf->userflags |= IB_PERSISTENT;
-				}
 			}
 			else if (ima->type == IMA_TYPE_COMPOSITE) {
 				/* requires lock/unlock, otherwise don't return image */
@@ -3097,10 +3093,14 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
 						ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
 						image_assign_ibuf(ima, ibuf, 0, frame);
 					}
-					ibuf->userflags |= IB_PERSISTENT;
 				}
 			}
 		}
+
+		/* We only want movies and sequences to be memory limited. */
+		if (ibuf != NULL && !ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
+			ibuf->userflags |= IB_PERSISTENT;
+		}
 	}
 
 	BKE_image_tag_time(ima);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 0bd1f97a279aaa45f51a156f3c44d98f458a9279..f831378ca5aeea285f54b808f33da5706330b4df 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -808,6 +808,32 @@ void *BKE_libblock_copy_ex(Main *bmain, ID *id)
 	return idn;
 }
 
+void *BKE_libblock_copy_nolib(ID *id)
+{
+	ID *idn;
+	size_t idn_len;
+
+	idn = alloc_libblock_notest(GS(id->name));
+	assert(idn != NULL);
+
+	BLI_strncpy(idn->name, id->name, sizeof(idn->name));
+
+	idn_len = MEM_allocN_len(idn);
+	if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
+		const char *cp = (const char *)id;
+		char *cpn = (char *)idn;
+
+		memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
+	}
+
+	id->newid = idn;
+	idn->flag |= LIB_NEW;
+
+	BKE_libblock_copy_data(idn, id, false);
+
+	return idn;
+}
+
 void *BKE_libblock_copy(ID *id)
 {
 	return BKE_libblock_copy_ex(G.main, id);
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 9b7886ece971928bb640273d589362e141a64e72..d08b7316e612d5b9c621670b6c43ad3844ef5809 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -734,6 +734,7 @@ Mask *BKE_mask_new(Main *bmain, const char *name)
 	return mask;
 }
 
+/* TODO(sergey): Use generic BKE_libblock_copy_nolib() instead. */
 Mask *BKE_mask_copy_nolib(Mask *mask)
 {
 	Mask *mask_new;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 5f6331315f8ac20bb543b6a6e36dfcb2abd59feb..f3e38d84c331f9e752d7c78a1e30030b5abe6f64 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -256,8 +256,7 @@ Material *localize_material(Material *ma)
 	Material *man;
 	int a;
 	
-	man = BKE_libblock_copy(&ma->id);
-	BLI_remlink(&G.main->mat, man);
+	man = BKE_libblock_copy_nolib(&ma->id);
 
 	/* no increment for texture ID users, in previewrender.c it prevents decrement */
 	for (a = 0; a < MAX_MTEX; a++) {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index a41b47809eb60ef6ef6307342f762af4225f2a05..c8fe99bab91e30f87c6bc29618f8859d63f70c9c 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -279,17 +279,8 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in
 	movieclip_open_anim_file(clip);
 
 	if (clip->anim) {
-		int dur;
-		int fra;
-
-		dur = IMB_anim_get_duration(clip->anim, tc);
-		fra = framenr - clip->start_frame + clip->frame_offset;
-
-		if (fra < 0)
-			fra = 0;
-
-		if (fra > (dur - 1))
-			fra = dur - 1;
+		int dur = IMB_anim_get_duration(clip->anim, tc);
+		int fra = framenr - clip->start_frame + clip->frame_offset;
 
 		ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy);
 	}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index d6225560e325fc511fc5aaa924b39da946fc84dd..4fbc5c3f2d9936d6518eee4cf5bd034f1aa6a7d4 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1114,20 +1114,13 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
 	
 	if (ntree == NULL) return NULL;
 	
-	if (bmain) {
-		/* is ntree part of library? */
-		if (BLI_findindex(&bmain->nodetree, ntree) != -1)
-			newtree = BKE_libblock_copy(&ntree->id);
-		else
-			newtree = NULL;
+	/* is ntree part of library? */
+	if (bmain && BLI_findindex(&bmain->nodetree, ntree) >= 0) {
+		newtree = BKE_libblock_copy(&ntree->id);
 	}
-	else
-		newtree = NULL;
-	
-	if (newtree == NULL) {
-		newtree = MEM_dupallocN(ntree);
+	else {
+		newtree = BKE_libblock_copy_nolib(&ntree->id);
 		newtree->id.lib = NULL;	/* same as owning datablock id.lib */
-		BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
 	}
 
 	id_us_plus((ID *)newtree->gpd);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 0970af46a6b83c7d9f6062fd00f2516ee2e5c917..674c16383af8a42bda318191563e0043fcee72b0 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2843,7 +2843,8 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
 /* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
 void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
                                  Scene *scene, Object *ob,
-                                 RigidBodyWorld *rbw)
+                                 RigidBodyWorld *rbw,
+                                 const bool do_proxy_update)
 {
 	if (ob->recalc & OB_RECALC_ALL) {
 		/* speed optimization for animation lookups */
@@ -3036,8 +3037,10 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
 
 		/* the no-group proxy case, we call update */
 		if (ob->proxy_group == NULL) {
-			// printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
-			BKE_object_handle_update(eval_ctx, scene, ob->proxy);
+			if (do_proxy_update) {
+				// printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
+				BKE_object_handle_update(eval_ctx, scene, ob->proxy);
+			}
 		}
 	}
 }
@@ -3048,7 +3051,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
  */
 void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
 {
-	BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL);
+	BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL, true);
 }
 
 void BKE_object_sculpt_modifiers_changed(Object *ob)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 3a6e710d68c6e2d6fe1734d74544a65fb63128f3..ed0f8b2d8e4c82f2be3192167bd15a22d7923864 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3779,7 +3779,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
 		return 0;
 
 	if (pa) {
-		i = (pa->num_dmcache == DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache;
+		i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache;
 		if (i >= dm->getNumTessFaces(dm))
 			i = -1;
 	}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 110e91711f058bfc7ab692760c6de01a24fbb7ba..37eba4657ffd77a50952d0d0a3883da364cef4c4 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1270,7 +1270,7 @@ static void scene_update_all_bases(EvaluationContext *eval_ctx, Scene *scene, Sc
 	for (base = scene->base.first; base; base = base->next) {
 		Object *object = base->object;
 
-		BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world);
+		BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, true);
 
 		if (object->dup_group && (object->transflag & OB_DUPLIGROUP))
 			BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, object, object->dup_group);
@@ -1304,9 +1304,11 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
 		double start_time = 0.0;
 		bool add_to_stats = false;
 
-		PRINT("Thread %d: update object %s\n", threadid, object->id.name);
-
 		if (G.debug & G_DEBUG_DEPSGRAPH) {
+			if (object->recalc & OB_RECALC_ALL) {
+				printf("Thread %d: update object %s\n", threadid, object->id.name);
+			}
+
 			start_time = PIL_check_seconds_timer();
 
 			if (object->recalc & OB_RECALC_ALL) {
@@ -1319,7 +1321,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
 		 * separately from main thread because of we've got no idea about
 		 * dependencies inside the group.
 		 */
-		BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world);
+		BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, false);
 
 		/* Calculate statistics. */
 		if (add_to_stats) {
@@ -1335,7 +1337,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
 	}
 	else {
 		PRINT("Threda %d: update node %s\n", threadid,
-		      DAG_get_node_name(node));
+		      DAG_get_node_name(scene, node));
 	}
 
 	/* Update will decrease child's valency and schedule child with zero valency. */
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 86cf04eded82bbd0a0e19074b0d8022043147f71..7b9262320afd9c81f8090c9b1729db4df053d977 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1467,8 +1467,8 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
 
 	ibuf = seq_render_strip(context, seq, cfra);
 
-	rectx = (proxy_render_size * context->scene->r.xsch) / 100;
-	recty = (proxy_render_size * context->scene->r.ysch) / 100;
+	rectx = (proxy_render_size * ibuf->x) / 100;
+	recty = (proxy_render_size * ibuf->y) / 100;
 
 	if (ibuf->x != rectx || ibuf->y != recty) {
 		IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
@@ -1562,6 +1562,7 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
 	                                    (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
 	                                    (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100);
 	render_context.skip_cache = true;
+	render_context.is_proxy_render = true;
 
 	for (cfra = seq->startdisp + seq->startstill;  cfra < seq->enddisp - seq->endstill; cfra++) {
 		if (context->size_flags & IMB_PROXY_25) {
@@ -1919,10 +1920,14 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float
  *  - Premultiply
  */
 
-int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *UNUSED(context), Sequence *seq, float UNUSED(cfra))
+int BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, Sequence *seq, float UNUSED(cfra))
 {
 	float mul;
 
+	if (context->is_proxy_render) {
+		return FALSE;
+	}
+
 	if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
 		return TRUE;
 	}
@@ -2806,8 +2811,12 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
 				if (ibuf == NULL)
 					ibuf = do_render_strip_uncached(context, seq, cfra);
 
-				if (ibuf)
+				if (ibuf) {
+					if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
+						is_proxy_image = (context->preview_render_size != 100);
+					}
 					BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+				}
 			}
 		}
 
@@ -2826,8 +2835,11 @@ static ImBuf *seq_render_strip(const SeqRenderData *context, Sequence *seq, floa
 		sequencer_imbuf_assign_spaces(context->scene, ibuf);
 	}
 
-	if (ibuf->x != context->rectx || ibuf->y != context->recty)
+	if (context->is_proxy_render == false &&
+	    (ibuf->x != context->rectx || ibuf->y != context->recty))
+	{
 		use_preprocess = TRUE;
+	}
 
 	if (use_preprocess)
 		ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
@@ -4011,11 +4023,19 @@ void BKE_sequencer_offset_animdata(Scene *scene, Sequence *seq, int ofs)
 	for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) {
 		if (strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
 			unsigned int i;
-			for (i = 0; i < fcu->totvert; i++) {
-				BezTriple *bezt = &fcu->bezt[i];
-				bezt->vec[0][0] += ofs;
-				bezt->vec[1][0] += ofs;
-				bezt->vec[2][0] += ofs;
+			if (fcu->bezt) {
+				for (i = 0; i < fcu->totvert; i++) {
+					BezTriple *bezt = &fcu->bezt[i];
+					bezt->vec[0][0] += ofs;
+					bezt->vec[1][0] += ofs;
+					bezt->vec[2][0] += ofs;
+				}
+			}
+			if (fcu->fpt) {
+				for (i = 0; i < fcu->totvert; i++) {
+					FPoint *fpt = &fcu->fpt[i];
+					fpt->vec[0] += ofs;
+				}
 			}
 		}
 	}
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index a7e3c12e5d7978c3e71c2dffd587cda7a3051f4f..1dfdc5c3c74a1b5b2a9dc582e86f4ce369a233da 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -205,14 +205,16 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
 			return false;
 		}
 		
-		/* get remaining two faces */
-		f = e->l->f;
-		f2 = e->l->radial_next->f;
-
-		if (f != f2) {
-			/* join two remaining faces */
-			if (!BM_faces_join_pair(bm, f, f2, e, true)) {
-				return false;
+		if (e->l) {
+			/* get remaining two faces */
+			f = e->l->f;
+			f2 = e->l->radial_next->f;
+
+			if (f != f2) {
+				/* join two remaining faces */
+				if (!BM_faces_join_pair(bm, f, f2, e, true)) {
+					return false;
+				}
 			}
 		}
 	}
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index a255c534736471b15dca4d17c559ce7b95d94a25..29522b627075e355fdb959b1dcc5b532f3e30e71 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -395,6 +395,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 	const float thickness          = BMO_slot_float_get(op->slots_in, "thickness");
 	const float depth              = BMO_slot_float_get(op->slots_in, "depth");
 
+	/* store vert coords in normals, needed for 'use_edge_rail' */
+#define USE_VERTNORMAL_HACK
+
 	int edge_info_len = 0;
 
 	BMIter iter;
@@ -453,6 +456,11 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 
 			BM_elem_index_set(e, -1); /* set_dirty! */
 		}
+
+#ifdef USE_VERTNORMAL_HACK
+			copy_v3_v3(e->v1->no, e->v1->co);
+			copy_v3_v3(e->v2->no, e->v2->co);
+#endif
 	}
 	bm->elem_index_dirty |= BM_EDGE;
 
@@ -564,6 +572,9 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 
 				/* in some cases the edge doesn't split off */
 				if (r_vout_len == 1) {
+#ifdef USE_VERTNORMAL_HACK
+					copy_v3_v3(vout[0]->no, vout[0]->co);
+#endif
 					MEM_freeN(vout);
 					continue;
 				}
@@ -575,6 +586,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 					int vert_edge_tag_tot = 0;
 					int vecpair[2];
 
+#ifdef USE_VERTNORMAL_HACK
+					copy_v3_v3(v_split->no, v_split->co);
+#endif
+
 					/* find adjacent */
 					BM_ITER_ELEM (e, &iter, v_split, BM_EDGES_OF_VERT) {
 						if (BM_elem_flag_test(e, BM_ELEM_TAG) &&
@@ -628,9 +643,22 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 								if (l_other_a->v == l_other_b->v) {
 									/* both edges faces are adjacent, but we don't need to know the shared edge
 									 * having both verts is enough. */
-									sub_v3_v3v3(tvec, l_other_a->v->co, v_split->co);
+									const float *co_other;
+
+									/* note that we can't use 'l_other_a->v' directly since it
+									 * may be inset and give a feedback loop. */
+#ifdef USE_VERTNORMAL_HACK
+									co_other = l_other_a->v->no;
+#else
+									co_other = l_other_a->v->co;
+#endif
+
+									sub_v3_v3v3(tvec, co_other, v_split->co);
 									is_mid = false;
 								}
+
+								/* distable gives odd results at times, see [#39288] */
+#if 0
 								else if (compare_v3v3(f_a->no, f_b->no, 0.001f) == false) {
 									/* epsilon increased to fix [#32329] */
 
@@ -645,6 +673,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
 									copy_v3_v3(tvec, tno);
 									is_mid = false;
 								}
+#endif
 							}
 							normalize_v3(tvec);
 
diff --git a/source/blender/bmesh/tools/bmesh_wireframe.c b/source/blender/bmesh/tools/bmesh_wireframe.c
index db4601d6134f51be5537a602f5ffdb6009e912d7..824a41645599d19ce2a673c1fe7c62cd61267f38 100644
--- a/source/blender/bmesh/tools/bmesh_wireframe.c
+++ b/source/blender/bmesh/tools/bmesh_wireframe.c
@@ -529,8 +529,62 @@ void BM_mesh_wireframe(
 	}
 
 	if (use_replace) {
-		for (i = 0; i < totvert_orig; i++) {
-			BM_vert_kill(bm, verts_src[i]);
+
+		if (use_tag) {
+			/* only remove faces which are original and used to make wire,
+			 * use 'verts_pos' and 'verts_neg' to avoid a feedback loop. */
+
+			/* vertex must be from 'verts_src' */
+#define VERT_DUPE_TEST_ORIG(v)  (verts_neg[BM_elem_index_get(v)] != NULL)
+#define VERT_DUPE_TEST(v)       (verts_pos[BM_elem_index_get(v)] != NULL)
+#define VERT_DUPE_CLEAR(v)     { verts_pos[BM_elem_index_get(v)]  = NULL; } (void)0
+
+			/* first ensure we keep all verts which are used in faces that weren't
+			 * entirely made into wire. */
+			BM_ITER_MESH (f_src, &iter, bm, BM_FACES_OF_MESH) {
+				int mix_flag = 0;
+				BMLoop *l_iter, *l_first;
+
+				/* skip new faces */
+				if (BM_elem_index_get(f_src) == -1) {
+					continue;
+				}
+
+				l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+				do {
+					mix_flag |= (VERT_DUPE_TEST_ORIG(l_iter->v) ? 1 : 2);
+					if (mix_flag == (1 | 2)) {
+						break;
+					}
+				} while ((l_iter = l_iter->next) != l_first);
+
+				if (mix_flag == (1 | 2)) {
+					l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+					do {
+						VERT_DUPE_CLEAR(l_iter->v);
+					} while ((l_iter = l_iter->next) != l_first);
+				}
+			}
+
+			/* now remove any verts which were made into wire by all faces */
+			for (i = 0; i < totvert_orig; i++) {
+				v_src = verts_src[i];
+				BLI_assert(i == BM_elem_index_get(v_src));
+				if (VERT_DUPE_TEST(v_src)) {
+					BM_vert_kill(bm, v_src);
+				}
+			}
+
+#undef VERT_DUPE_TEST_ORIG
+#undef VERT_DUPE_TEST
+#undef VERT_DUPE_CLEAR
+
+		}
+		else {
+			/* simple case, no tags - replace all */
+			for (i = 0; i < totvert_orig; i++) {
+				BM_vert_kill(bm, verts_src[i]);
+			}
 		}
 	}
 
diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index 3b0e9f239bb147ef306414208f176cb152adbfd3..6c07aadc3aa825bf6196c4b1de0beb90857ffa63 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -109,4 +109,13 @@ typedef enum OrderOfChunks {
 
 #define COM_BLUR_BOKEH_PIXELS 512
 
+/**
+ * The fast gaussien blur is not an accurate blur.
+ * This setting can be used to increase/decrease the 
+ * amount of the input data. (dependent area of interest)
+ *
+ * Fix for: T39307
+ */
+#define COM_FAST_GAUSSIAN_MULTIPLIER 3
+
 #endif  /* __COM_DEFINES_H__ */
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index a6be9254f6fd5232dac7067e92d92517a668ac49..ff53ef22e29c4317e6fcf71e04ec020f448ad671 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -47,10 +47,11 @@ bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output)
 {
 	// m_data->sizex * m_size should be enough? For some reason there
 	// seem to be errors in the boundary between tiles.
-	int sx = this->m_data->sizex * this->m_size * 2;
+	float size = this->m_size * COM_FAST_GAUSSIAN_MULTIPLIER;
+	int sx = this->m_data->sizex * size;
 	if (sx < 1)
 		sx = 1;
-	int sy = this->m_data->sizey * this->m_size * 2;
+	int sy = this->m_data->sizey * size;
 	if (sy < 1)
 		sy = 1;
 
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 0aff3b81ec93092e53a26e4457d91912ec0c1799..1cd41bd110d2281b0c5c0fa521691f2b3adc8a64 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -93,6 +93,8 @@ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist
 void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
 void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist);
 
+void ED_view3d_lastview_store(struct RegionView3D *rv3d);
+
 /* Depth buffer */
 void  ED_view3d_depth_update(struct ARegion *ar);
 float ED_view3d_depth_read_cached(struct ViewContext *vc, int x, int y);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index f1c0df23fc96e50db70cc100fc599df846a2849d..0768d5569112c5efa12edf35c2d139a6fdd623df 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2374,6 +2374,11 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
 	data->selextend = 0;
 	data->selstartx = 0.0f;
 
+#ifdef USE_DRAG_MULTINUM
+	/* this can happen from multi-drag */
+	data->applied_interactive = false;
+#endif
+
 	/* set cursor pos to the end of the text */
 	but->editstr = data->str;
 	but->pos = len;
@@ -3477,10 +3482,21 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 			}
 		}
 		else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
-			if (data->dragchange)
-				button_activate_state(C, but, BUTTON_STATE_EXIT);
-			else
+			if (data->dragchange) {
+#ifdef USE_DRAG_MULTINUM
+				/* if we started multibutton but didnt drag, then edit */
+				if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+					click = 1;
+				}
+				else
+#endif
+				{
+					button_activate_state(C, but, BUTTON_STATE_EXIT);
+				}
+			}
+			else {
 				click = 1;
+			}
 		}
 		else if (event->type == MOUSEMOVE) {
 			const enum eSnapType snap = ui_event_to_snap(event);
@@ -3763,10 +3779,21 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 			}
 		}
 		else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
-			if (data->dragchange)
-				button_activate_state(C, but, BUTTON_STATE_EXIT);
-			else
+			if (data->dragchange) {
+#ifdef USE_DRAG_MULTINUM
+				/* if we started multibutton but didnt drag, then edit */
+				if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+					click = 1;
+				}
+				else
+#endif
+				{
+					button_activate_state(C, but, BUTTON_STATE_EXIT);
+				}
+			}
+			else {
 				click = 1;
+			}
 		}
 		else if (event->type == MOUSEMOVE) {
 #ifdef USE_DRAG_MULTINUM
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index b5255eb051604862e6b0d6a396a96b977533272c..55f35a93692bcc0fb760579725c2f162fa0e6edf 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -888,7 +888,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
 		EnumPropertyItem *item, *item_array = NULL;
 		bool free;
 		uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
-		uiLayout *column = uiLayoutColumn(split, false);
+		uiLayout *column = uiLayoutColumn(split, layout->align);
 
 		RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, NULL, &free);
 		for (item = item_array; item->identifier; item++) {
@@ -912,7 +912,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
 				if (item->name) {
 					uiBut *but;
 					if (item != item_array) {
-						column = uiLayoutColumn(split, false);
+						column = uiLayoutColumn(split, layout->align);
 						/* inconsistent, but menus with labels do not look good flipped */
 						block->flag |= UI_BLOCK_NO_FLIP;
 					}
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 2ca5301c89ce4a7c0f31e5917913d0c5847e6c32..aa3a2c8324353c64409d0d93f35da0d18e835158 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -503,7 +503,7 @@ void MESH_OT_inset(wmOperatorType *ot)
 	RNA_def_boolean(ot->srna, "use_boundary",        true, "Boundary",  "Inset face boundaries");
 	RNA_def_boolean(ot->srna, "use_even_offset",     true, "Offset Even",      "Scale the offset to give more even thickness");
 	RNA_def_boolean(ot->srna, "use_relative_offset", false, "Offset Relative", "Scale the offset by surrounding geometry");
-	RNA_def_boolean(ot->srna, "use_edge_rail",     true, "Edge Rail", "Inset the region along existing edges");
+	RNA_def_boolean(ot->srna, "use_edge_rail",       false, "Edge Rail", "Inset the region along existing edges");
 
 	prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f);
 	/* use 1 rather then 10 for max else dragging the button moves too far */
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index b29fafea90de7e610e7780520435bbe6c5f9bc72..182a9f709681a7e6a9ca0aac929223a8997f2268 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1478,8 +1478,13 @@ static void curvetomesh(Main *bmain, Scene *scene, Object *ob)
 	convert_ensure_curve_cache(bmain, scene, ob);
 	BKE_mesh_from_nurbs(ob); /* also does users */
 
-	if (ob->type == OB_MESH)
+	if (ob->type == OB_MESH) {
 		BKE_object_free_modifiers(ob);
+
+		/* Game engine defaults for mesh objects */
+		ob->body_type = OB_BODY_TYPE_STATIC;
+		ob->gameflag = OB_PROP | OB_COLLISION;
+	}
 }
 
 static int convert_poll(bContext *C)
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 66fa5787e5dfe8b92cbd09749c153436d3c56a2b..23ead971cd3552411db2069eedcc5352749b211b 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1514,19 +1514,22 @@ void ED_screen_set(bContext *C, bScreen *sc)
 
 		/* we put timer to sleep, so screen_exit has to think there's no timer */
 		oldscreen->animtimer = NULL;
-		if (wt)
+		if (wt) {
 			WM_event_timer_sleep(wm, win, wt, true);
-		
+		}
+
 		ED_screen_exit(C, win, oldscreen);
 
 		/* Same scene, "transfer" playback to new screen. */
-		if (oldscene == sc->scene) {
-			sc->animtimer = wt;
-		}
-		/* Else, stop playback. */
-		else {
-			oldscreen->animtimer = wt;
-			ED_screen_animation_play(C, 0, 0);
+		if (wt) {
+			if (oldscene == sc->scene) {
+				sc->animtimer = wt;
+			}
+			/* Else, stop playback. */
+			else {
+				oldscreen->animtimer = wt;
+				ED_screen_animation_play(C, 0, 0);
+			}
 		}
 
 		win->screen = sc;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 2cb28ebba90c8f781a88f55f694b1cc751fc1c16..0d0ce259174884ad727595c6dad26974a7dd09d7 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2848,6 +2848,10 @@ static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar,
 {
 	RegionView3D *rv3d = ar->regiondata;
 
+	if (persp == RV3D_CAMOB) {
+		ED_view3d_lastview_store(rv3d);
+	}
+
 	rv3d->viewlock = viewlock;
 	rv3d->view = view;
 	rv3d->persp = persp;
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 1a5ccc8f8bd13915d01eca9c20c19abab468bdb8..a3e69a1024b8f0dcc1478c793a8875d4c209ac2a 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -45,6 +45,7 @@
 #include "BKE_brush.h"
 #include "BKE_context.h"
 #include "BKE_image.h"
+#include "BKE_node.h"
 #include "BKE_paint.h"
 #include "BKE_colortools.h"
 
@@ -60,6 +61,10 @@
  * removed eventually (TODO) */
 #include "sculpt_intern.h"
 
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
 /* TODOs:
  *
  * Some of the cursor drawing code is doing non-draw stuff
@@ -197,6 +202,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
 
 		pool = BKE_image_pool_new();
 
+		if (mtex->tex && mtex->tex->nodetree)
+			ntreeTexBeginExecTree(mtex->tex->nodetree);  /* has internal flag to detect it only does it once */
+
 #pragma omp parallel for schedule(static)
 		for (j = 0; j < size; j++) {
 			int i;
@@ -241,7 +249,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
 					if (col) {
 						float rgba[4];
 
-						paint_get_tex_pixel_col(mtex, x, y, rgba, pool);
+						paint_get_tex_pixel_col(mtex, x, y, rgba, pool, omp_get_thread_num());
 
 						buffer[index * 4]     = rgba[0] * 255;
 						buffer[index * 4 + 1] = rgba[1] * 255;
@@ -249,7 +257,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
 						buffer[index * 4 + 3] = rgba[3] * 255;
 					}
 					else {
-						float avg = paint_get_tex_pixel(mtex, x, y, pool);
+						float avg = paint_get_tex_pixel(mtex, x, y, pool, omp_get_thread_num());
 
 						avg += br->texture_sample_bias;
 
@@ -272,6 +280,9 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
 			}
 		}
 
+		if (mtex->tex && mtex->tex->nodetree)
+			ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
+
 		if (pool)
 			BKE_image_pool_free(pool);
 
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 6dd42380a119a6e75288f1d7e4402293a51d7721..af9ac6dd89de5e47db904c0d4ee61298e9007af2 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -198,8 +198,8 @@ void paint_calc_redraw_planes(float planes[4][4],
                               const struct rcti *screen_rect);
 
 float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
-float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool);
-void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool);
+float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
+void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread);
 int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface);
 void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]);
 void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index e6efba4fa0c88bac0e2b4e6ed342ba4f29149392..de09709fcce75ee2abe603eb66080b4b2a34072b 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -164,26 +164,25 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
 	return len_v3(delta) / scale;
 }
 
-float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool)
+float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
 {
 	float intensity, rgba[4];
 	float co[3] = {u, v, 0.0f};
 
 	externtex(mtex, co, &intensity,
-		                   rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);
+						   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
 
 	return intensity;
 }
 
-void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool)
+void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread)
 {
 	float co[3] = {u, v, 0.0f};
 	int hasrgb;
 	float intensity;
 
 	hasrgb = externtex(mtex, co, &intensity,
-		                   rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool);
-
+						   rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
 	if (!hasrgb) {
 		rgba[0] = intensity;
 		rgba[1] = intensity;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index a04e15d3729acfe9424d9c1400401c80ad8e98c1..ae729248f7e7c6a8d3f844dc677abae6a7ad4dc2 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -153,6 +153,10 @@ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index,
 
 			vp_handle->dists_sq[index] = dist_sq;
 		}
+		else if (vp_handle->dists_sq[index] != FLT_MAX) {
+			/* already initialized & couldn't project this 'co' */
+			return;
+		}
 	}
 	/* continue with regular functionality */
 
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index d74e9c9e17b82b9792e535f2de342e498114085f..35de6af2531a33bda7709ad7ff33be59f5dba1c6 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -104,6 +104,19 @@
 #include <omp.h>
 #endif
 
+#if defined(__APPLE__)
+#include <sys/sysctl.h>
+
+/* Query how many cores not counting HT aka physical cores we've got. */
+static int system_physical_thread_count(void)
+{
+	int pcount;
+	size_t pcount_len = sizeof(pcount);
+	sysctlbyname("hw.physicalcpu", &pcount, &pcount_len, NULL, 0);
+	return pcount;
+}
+#endif  /* __APPLE__ */
+
 void ED_sculpt_get_average_stroke(Object *ob, float stroke[3])
 {
 	if (ob->sculpt->last_stroke_valid && ob->sculpt->average_stroke_counter > 0) {
@@ -230,7 +243,7 @@ typedef struct StrokeCache {
 	float initial_mouse[2];
 
 	/* Pre-allocated temporary storage used during smoothing */
-	int num_threads;
+	int num_threads, max_threads;
 	float (**tmpgrid_co)[3], (**tmprow_co)[3];
 	float **tmpgrid_mask, **tmprow_mask;
 
@@ -924,6 +937,7 @@ static float tex_strength(SculptSession *ss, Brush *br,
 	MTex *mtex = &br->mtex;
 	float avg = 1;
 	float rgba[4];
+	int thread_num;
 
 	if (!mtex->tex) {
 		avg = 1;
@@ -966,7 +980,12 @@ static float tex_strength(SculptSession *ss, Brush *br,
 			x += br->mtex.ofs[0];
 			y += br->mtex.ofs[1];
 
-			avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool);
+#ifdef _OPENMP
+			thread_num = omp_get_thread_num();
+#else
+			thread_num = 0;
+#endif
+			avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool, thread_num);
 
 			avg += br->texture_sample_bias;
 		}
@@ -3766,16 +3785,21 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
 	 * Justification: Empirically I've found that two threads per
 	 * processor gives higher throughput. */
 	if (sd->flags & SCULPT_USE_OPENMP) {
-		cache->num_threads = 2 * omp_get_num_procs();
-		omp_set_num_threads(cache->num_threads);
-	}
-	else
+#if defined(__APPLE__)
+		cache->num_threads = system_physical_thread_count();
+#else
+		cache->num_threads = omp_get_num_procs();
 #endif
-	{
-		(void)sd;
+	}
+	else {
 		cache->num_threads = 1;
 	}
-
+	cache->max_threads = omp_get_max_threads();
+	omp_set_num_threads(cache->num_threads);
+#else
+	(void)sd;
+	cache->num_threads = 1;
+#endif
 	if (ss->multires) {
 		int i, gridsize, array_mem_size;
 		BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL,
@@ -3802,6 +3826,10 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss)
 
 static void sculpt_omp_done(SculptSession *ss)
 {
+#ifdef _OPENMP
+	omp_set_num_threads(ss->cache->max_threads);
+#endif
+
 	if (ss->multires) {
 		int i;
 
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 18652aabefed8562e457ffe079439c78426b30f4..d417776b1f2793eb3f2a7a81ef6df9dc1a69a7fd 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -974,6 +974,10 @@ static bool prefetch_check_early_out(const bContext *C)
 	int first_uncached_frame, end_frame;
 	int clip_len;
 
+	if (clip == NULL) {
+		return true;
+	}
+
 	clip_len = BKE_movieclip_get_duration(clip);
 
 	/* check whether all the frames from prefetch range are cached */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index bb6c50d62244da8030fca85d00ba2dabf0c246b4..0e152dbebcf0390fd6ca9119ddc999e570d85f9e 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -110,10 +110,21 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2])
 	}
 
 	if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) {
+		float dx, dy;
+
 		ED_space_clip_get_size(sc, &width, &height);
 
-		sc->xof += ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
-		sc->yof += ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
+		dx = ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
+		dy= ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
+
+		if (sc->flag & SC_LOCK_SELECTION) {
+			sc->xlockof += dx;
+			sc->ylockof += dy;
+		}
+		else {
+			sc->xof += dx;
+			sc->yof += dy;
+		}
 	}
 }
 
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 2f1d78b2ccda5ca109444eb047b2e8a132d36b4a..c56bc33ef1584d20faf99a27f6474635acbe2bf4 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -577,7 +577,10 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
 	RNA_boolean_set(kmi->ptr, "sequence", TRUE);
 
 	/* mode */
-	WM_keymap_add_menu(keymap, "CLIP_MT_select_mode", TABKEY, KM_PRESS, 0, 0);
+	kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", TABKEY, KM_PRESS, 0, 0);
+	RNA_string_set(kmi->ptr, "data_path", "space_data.mode");
+	RNA_string_set(kmi->ptr, "value_1", "TRACKING");
+	RNA_string_set(kmi->ptr, "value_2", "MASK");
 
 	WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0);
 
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 6f44b47ed610169354e1c6556ebd113659767cd4..2b7bb01cea17f18dd920680473496ae55a37b97b 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1309,10 +1309,13 @@ static void track_markers_updatejob(void *tmv)
 static void track_markers_endjob(void *tmv)
 {
 	TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
+	wmWindowManager *wm = tmj->main->wm.first;
 
 	tmj->clip->tracking_context = NULL;
 	tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra);
-	ED_update_for_newframe(tmj->main, tmj->scene, 0);
+	if (wm != NULL) {
+		ED_update_for_newframe(tmj->main, tmj->scene, 0);
+	}
 
 	BKE_tracking_context_sync(tmj->context);
 	BKE_tracking_context_finish(tmj->context);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index effb8eb7de5157f7eb65d8a6df9a79e9dcd046cf..f51d6cc366039931856890ddb795fc52a05a939b 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -37,6 +37,7 @@
 #include "DNA_object_types.h"
 #include "DNA_space_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
 
 #include "BKE_context.h"
 #include "BKE_curve.h"
@@ -923,7 +924,7 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN
 	PointerRNA scene = CTX_data_pointer_get(C, "scene");
 	if (scene.data) {
 		PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
-		if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+		if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0))
 			uiItemL(layout, IFACE_("SSS not supported on GPU"), ICON_ERROR);
 	}
 
@@ -933,12 +934,12 @@ static void node_shader_buts_subsurface(uiLayout *layout, bContext *C, PointerRN
 
 static void node_shader_buts_volume(uiLayout *layout, bContext *C, PointerRNA *UNUSED(ptr))
 {
-	/* SSS does not work on GPU yet */
+	/* Volume does not work on GPU yet */
 	PointerRNA scene = CTX_data_pointer_get(C, "scene");
 	if (scene.data) {
 		PointerRNA cscene = RNA_pointer_get(&scene, "cycles");
 
-		if (cscene.data && RNA_enum_get(&cscene, "device") == 1)
+		if (cscene.data && (RNA_enum_get(&cscene, "device") == 1 && U.compute_device_type != 0))
 			uiItemL(layout, IFACE_("Volumes not supported on GPU"), ICON_ERROR);
 	}
 }
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index d44a3e60a3f1c00a7753be2f1490607e1ab7cc28..4db63a462e71c3f7e85509de8d282c56d6f175fa 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -481,7 +481,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
 					char newname[sizeof(bone->name)];
 					
 					/* always make current object active */
-					tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+					tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
 					ob = OBACT;
 					
 					/* restore bone name */
@@ -498,8 +498,10 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
 					char newname[sizeof(pchan->name)];
 					
 					/* always make current pose-bone active */
-					tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+					tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, true);
 					ob = OBACT;
+
+					BLI_assert(ob->type == OB_ARMATURE);
 					
 					/* restore bone name */
 					BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
@@ -1154,7 +1156,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
 					active = OL_DRAWSEL_NORMAL;
 				}
 				else {
-					active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE);
+					active = tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false);
 				}
 			}
 			else {
@@ -1295,7 +1297,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
 				active = OL_DRAWSEL_ACTIVE;
 			}
 			else {
-				if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE)) {
+				if (tree_element_active(C, scene, soops, te, OL_SETSEL_NONE, false)) {
 					glColor4ub(220, 220, 255, alpha);
 					active = OL_DRAWSEL_ACTIVE;
 				}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index b1278c7cc076331d3c66d6c0ca516c70cb72c267..317d33dd3e21ed4a8b9936ce621e32395ab89b01 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -180,9 +180,8 @@ void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
 eOLDrawState tree_element_type_active(
         struct bContext *C, struct Scene *scene, struct SpaceOops *soops,
         TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive);
-eOLDrawState tree_element_active(
-        struct bContext *C, struct Scene *scene, SpaceOops *soops,
-        TreeElement *te, const eOLSetState set);
+eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops,
+                                 TreeElement *te, const eOLSetState set, const bool handle_all_types);
 int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive);
 
 /* outliner_edit.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 688695e3ded51348c6398e8d97bf283304981654..51db965b791fc1fe10618d9ea3fb8263d1eef84e 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -801,14 +801,17 @@ static eOLDrawState tree_element_active_keymap_item(
 /* ---------------------------------------------- */
 
 /* generic call for ID data check or make/check active in UI */
-eOLDrawState tree_element_active(
-        bContext *C, Scene *scene, SpaceOops *soops,
-        TreeElement *te, const eOLSetState set)
+eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te,
+                                 const eOLSetState set, const bool handle_all_types)
 {
-
 	switch (te->idcode) {
-		/* Note: no ID_OB: objects are handled specially to allow multiple
+		/* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple
 		 * selection. See do_outliner_item_activate. */
+		case ID_OB:
+			if (handle_all_types) {
+				return tree_element_set_active_object(C, scene, soops, te, set, false);
+			}
+			break;
 		case ID_MA:
 			return tree_element_active_material(C, scene, soops, te, set);
 		case ID_WO:
@@ -952,7 +955,7 @@ static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Sp
 					WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
 				}
 				else {  // rest of types
-					tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL);
+					tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false);
 				}
 
 			}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 1464d39ff238aa549a6625b8c37275b9ef8dddb5..3a9d97001fb18bf7772b77b6a52bd7ffe0dc0d97 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2296,7 +2296,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
 	float facx = BLI_rcti_size_x(&v2d->mask) / winx;
 	float facy = BLI_rcti_size_y(&v2d->mask) / winy;
 
-	BLI_rctf_resize(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1);
+	BLI_rctf_resize(&v2d->cur, floorf(winx * facx * ratio + 0.5f), floorf(winy * facy * ratio + 0.5f));
 
 	ED_region_tag_redraw(CTX_wm_region(C));
 
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ea81bb2b85712c0bca600dcc98ace38a44cc9fb7..57d6f0534261a6f60d1b2ef58de572ea435c6751 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -3590,9 +3590,8 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
 				if (!rv3d->smooth_timer) {
 					/* store settings of current view before allowing overwriting with camera view
 					 * only if we're not currently in a view transition */
-					copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
-					rv3d->lview = rv3d->view;
-					rv3d->lpersp = rv3d->persp;
+
+					ED_view3d_lastview_store(rv3d);
 				}
 
 #if 0
@@ -4733,6 +4732,18 @@ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], co
 	BKE_object_apply_mat4(ob, mat, true, true);
 }
 
+/**
+ * Use to store the last view, before entering camera view.
+ */
+void ED_view3d_lastview_store(RegionView3D *rv3d)
+{
+	copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
+	rv3d->lview = rv3d->view;
+	if (rv3d->persp != RV3D_CAMOB) {
+		rv3d->lpersp = rv3d->persp;
+	}
+}
+
 BGpic *ED_view3D_background_image_new(View3D *v3d)
 {
 	BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 83e4f112a8c9294076ae32828de098d14f6ef4f5..20ef59708a65da70f780f690b676fc12b999adc9 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -417,11 +417,7 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
 	ED_view3d_context_user_region(C, &v3d, &ar);
 	rv3d = ar->regiondata;
 
-	copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
-	rv3d->lview = rv3d->view;
-	if (rv3d->persp != RV3D_CAMOB) {
-		rv3d->lpersp = rv3d->persp;
-	}
+	ED_view3d_lastview_store(rv3d);
 
 	BKE_object_tfm_protected_backup(v3d->camera, &obtfm);
 
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 24f51635e07dbc86ef47f6b8a90406cfadf32322..5eca44c1ba5603b087f802c196fcabb7571d87a1 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -137,7 +137,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3])
 
 	snapGridIncrement(t, vec);
 
-	if (t->num.flag & T_NULL_ONE) {
+	if (t->flag & T_NULL_ONE) {
 		if (!(t->con.mode & CON_AXIS0))
 			vec[0] = 1.0f;
 
@@ -970,13 +970,13 @@ static void setNearestAxis3d(TransInfo *t)
 		sub_v2_v2v2(axis, axis_2d, t->center2d);
 		axis[2] = 0.0f;
 
-		if (normalize_v3(axis) != 0.0f) {
+		if (normalize_v3(axis) > 1e-3f) {
 			project_v3_v3v3(proj, mvec, axis);
 			sub_v3_v3v3(axis, mvec, proj);
 			len[i] = normalize_v3(axis);
 		}
 		else {
-			len[i] = 10000000000.0f;
+			len[i] = 1e10f;
 		}
 	}
 
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index bb0a74f1e09ede856d1b99c638ae57db208c92d5..e49e5c941a63e86e033c32d09047bea29e588124 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -3845,13 +3845,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
 					
 				}
 				/* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...):
-				 *	- Check if we've got entire BezTriple selected and we're rotating that point,
+				 *	- Check if we've got entire BezTriple selected and we're scaling/rotating that point,
 				 *	  then check if we're using auto-handles.
 				 *	- If so, change them auto-handles to aligned handles so that handles get affected too
 				 */
-				if ((t->mode == TFM_ROTATION) &&
-				    ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) &&
-				    ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM))
+				if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) &&
+				    ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) &&
+				    ELEM(t->mode, TFM_ROTATION, TFM_RESIZE))
 				{
 					if (hdata && (sel1) && (sel3)) {
 						bezt->h1 = HD_ALIGN;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 1f3725a961aa911a82cbb8375d91f83149d98295..4c097ca7da6b619e556c5390aef056363b877c86 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -321,8 +321,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
 			n->val_org[idx] = n->val[idx];
 			n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE);
 
-			idx += event->ctrl ? -1 : 1;
-			idx %= idx_max + 1;
+			idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1);
 			n->idx = idx;
 			n->val[idx] = n->val_org[idx];
 			if (n->val_flag[idx] & NUM_EDITED) {
@@ -334,42 +333,48 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
 			}
 			return true;
 		case PADPERIOD:
+		case PERIODKEY:
 			/* Force numdot, some OSs/countries generate a comma char in this case, sic...  (T37992) */
 			ascii[0] = '.';
 			utf8_buf = ascii;
 			break;
+#if 0  /* Those keys are not directly accessible in all layouts, preventing to generate matching events.
+        * So we use a hack (ascii value) instead, see below.
+        */
 		case EQUALKEY:
-			/* XXX Advanced mode toggle, hack around keyboards without direct access to '=' nor '*'... */
-			ascii[0] = '=';
-			break;
 		case PADASTERKEY:
-			/* XXX Advanced mode toggle, hack around keyboards without direct access to '=' nor '*'... */
-			ascii[0] = '*';
+			if (!(n->flag & NUM_EDIT_FULL)) {
+				n->flag |= NUM_EDIT_FULL;
+				n->val_flag[idx] |= NUM_EDITED;
+				return true;
+			}
+			else if (event->ctrl) {
+				n->flag &= ~NUM_EDIT_FULL;
+				return true;
+			}
 			break;
+#endif
 		case PADMINUS:
 		case MINUSKEY:
 			if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
 				n->val_flag[idx] ^= NUM_NEGATE;
 				updated = true;
-				break;
 			}
-			/* fall-through */
+			break;
 		case PADSLASHKEY:
 		case SLASHKEY:
 			if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
 				n->val_flag[idx] ^= NUM_INVERSE;
 				updated = true;
-				break;
 			}
-			/* fall-through */
+			break;
 		case CKEY:
 			if (event->ctrl) {
 				/* Copy current str to the copypaste buffer. */
 				WM_clipboard_text_set(n->str, 0);
 				updated = true;
-				break;
 			}
-			/* fall-through */
+			break;
 		case VKEY:
 			if (event->ctrl) {
 				/* extract the first line from the clipboard */
@@ -377,9 +382,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
 				char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len);
 
 				if (pbuf) {
-					bool success;
-
-					success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
+					const bool success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
 
 					MEM_freeN(pbuf);
 					if (!success) {
@@ -389,15 +392,17 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
 					n->val_flag[idx] |= NUM_EDITED;
 				}
 				updated = true;
-				break;
 			}
-			/* fall-through */
+			break;
 		default:
-			utf8_buf = event->utf8_buf;
-			ascii[0] = event->ascii;
 			break;
 	}
 
+	if (!updated && !utf8_buf && (event->utf8_buf[0] || event->ascii)) {
+		utf8_buf = event->utf8_buf;
+		ascii[0] = event->ascii;
+	}
+
 	/* XXX Hack around keyboards without direct access to '=' nor '*'... */
 	if (ELEM(ascii[0], '=', '*')) {
 		if (!(n->flag & NUM_EDIT_FULL)) {
@@ -411,7 +416,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
 		}
 	}
 
-	if (utf8_buf && !utf8_buf[0] && ascii[0]) {
+	if ((!utf8_buf || !utf8_buf[0]) && ascii[0]) {
 		/* Fallback to ascii. */
 		utf8_buf = ascii;
 	}
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp
index e517bf4f1967e955437c0e2df899095eb3f0fb21..fbfa5b331e66a4a78f56a93f8d735877ba0337bb 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.cpp
+++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp
@@ -557,17 +557,20 @@ void FitCurveWrapper::FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, V
 	if (maxError < iterationError) {
 		for (i = 0; i < maxIterations; i++) {
 			uPrime = Reparameterize(d, first, last, u, bezCurve);
-			bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2);
-			maxError = ComputeMaxError(d, first, last,
-			bezCurve, uPrime, &splitPoint);
+
+			free((void *)u);
+			free((void *)bezCurve);
+			u = uPrime;
+
+			bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);
+			maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
+
 			if (maxError < error) {
 				DrawBezierCurve(3, bezCurve);
 				free((void *)u);
 				free((void *)bezCurve);
 				return;
 			}
-			free((void *)u);
-			u = uPrime;
 		}
 	}
 
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index abe13b85cd21daed1febf43ea04c809f1cf97cee..a750cf2f7cf23032cf9a3b2aa0794267d71a82a8 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -577,10 +577,10 @@ void transformVertex(const Vec3r& vert, const Matrix44r& matrix, Vec3r& res)
 
 void transformVertices(const vector<Vec3r>& vertices, const Matrix44r& trans, vector<Vec3r>& res)
 {
-	for (vector<Vec3r>::const_iterator v = vertices.begin(); v != vertices.end(); v++) {
-		Vec3r *res_tmp = new Vec3r;
-		transformVertex(*v, trans, *res_tmp);
-		res.push_back(*res_tmp);
+	size_t i;
+	res.resize(vertices.size());
+	for (i = 0; i < vertices.size(); i++) {
+		transformVertex(vertices[i], trans, res[i]);
 	}
 }
 
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h
index 02b738cc2cd7f13f6f7fb5511f95c3e274e35dd2..f4d6d869f1b7ae37261ebcde149852dba6cd9c25 100644
--- a/source/blender/imbuf/intern/IMB_allocimbuf.h
+++ b/source/blender/imbuf/intern/IMB_allocimbuf.h
@@ -35,6 +35,9 @@
 
 struct ImBuf;
 
+void imb_refcounter_lock_init(void);
+void imb_refcounter_lock_exit(void);
+
 bool imb_addencodedbufferImBuf(struct ImBuf *ibuf);
 bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf);
 
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index d7ca381bae6aa314bb24464133834876c951cd2a..d0e81f2f383a17c34bd391cad307ef060ef5c200 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -49,6 +49,19 @@
 #include "MEM_CacheLimiterC-Api.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_threads.h"
+
+static SpinLock refcounter_spin;
+
+void imb_refcounter_lock_init(void)
+{
+	BLI_spin_init(&refcounter_spin);
+}
+
+void imb_refcounter_lock_exit(void)
+{
+	BLI_spin_end(&refcounter_spin);
+}
 
 void imb_freemipmapImBuf(ImBuf *ibuf)
 {
@@ -154,10 +167,18 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf)
 void IMB_freeImBuf(ImBuf *ibuf)
 {
 	if (ibuf) {
+		bool needs_free = false;
+
+		BLI_spin_lock(&refcounter_spin);
 		if (ibuf->refcounter > 0) {
 			ibuf->refcounter--;
 		}
 		else {
+			needs_free = true;
+		}
+		BLI_spin_unlock(&refcounter_spin);
+
+		if (needs_free) {
 			imb_freerectImBuf(ibuf);
 			imb_freerectfloatImBuf(ibuf);
 			imb_freetilesImBuf(ibuf);
@@ -177,7 +198,9 @@ void IMB_freeImBuf(ImBuf *ibuf)
 
 void IMB_refImBuf(ImBuf *ibuf)
 {
+	BLI_spin_lock(&refcounter_spin);
 	ibuf->refcounter++;
+	BLI_spin_unlock(&refcounter_spin);
 }
 
 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c
index 9141dad6f9c33971b02bce3b19174f7497d61b9a..4097deb00edeaa3426acfb88e760f67bced26be5 100644
--- a/source/blender/imbuf/intern/module.c
+++ b/source/blender/imbuf/intern/module.c
@@ -26,12 +26,17 @@
 
 
 #include <stddef.h>
+
+#include "BLI_utildefines.h"
+
+#include "IMB_allocimbuf.h"
 #include "IMB_imbuf.h"
 #include "IMB_filetype.h"
 #include "IMB_colormanagement_intern.h"
 
 void IMB_init(void)
 {
+	imb_refcounter_lock_init();
 	imb_filetypes_init();
 	imb_tile_cache_init();
 	colormanagement_init();
@@ -42,5 +47,6 @@ void IMB_exit(void)
 	imb_tile_cache_exit();
 	imb_filetypes_exit();
 	colormanagement_exit();
+	imb_refcounter_lock_exit();
 }
 
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 07ce3c39d73c4c9ccab175f0496e06963ce538c5..f699afd3475a6064149d18a2d2d32310a22ba86a 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -200,6 +200,18 @@ static size_t IMB_get_size_in_memory(ImBuf *ibuf)
 	int a;
 	size_t size = 0, channel_size = 0;
 
+	/* Persistent images should have no affect on how "normal"
+	 * images are cached.
+	 *
+	 * This is a bit arbitrary, but would make it so only movies
+	 * and sequences are memory limited, keeping textures in the
+	 * memory in order to avoid constant file reload on viewport
+	 * update.
+	 */
+	if (ibuf->userflags & IB_PERSISTENT) {
+		return 0;
+	}
+
 	size += sizeof(ImBuf);
 
 	if (ibuf->rect)
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 05e9a4fa134e5e29a802e5cd47bbb8e15bc89078..eb8f94cbc6e40cd164994925ea676795947d2c21 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -859,7 +859,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
 	TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT,  RESUNIT_INCH);
 	if (TIFFWriteEncodedStrip(image, 0,
 	                          (bitspersample == 16) ? (unsigned char *)pixels16 : pixels,
-	                          ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
+	                          (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1)
 	{
 		fprintf(stderr,
 		        "imb_savetiff: Could not write encoded TIFF.\n");
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 7efd0223368d9cb5f36ed0123725c12e6646f7e9..087f26dda442b53096fb8dfac9e58ca0a77284f0 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -179,6 +179,7 @@ const char *imb_ext_audio[] = {
 	".aif",
 	".aiff",
 	".m4a",
+	".mka",
 	NULL
 };
 
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 86ef2f1b74fd4ab63577cbd75257e3d0c017b49d..2f867fe95e16723c73bdd29be5c181f8dd1ff8b2 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -2035,7 +2035,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
 	BLI_assert(RNA_property_array_check(prop) != false);
 
 	if ((idprop = rna_idproperty_check(&prop, ptr))) {
-		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
 		if (prop->arraydimension == 0)
 			values[0] = RNA_property_int_get(ptr, prop);
 		else
@@ -2124,7 +2124,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
 	BLI_assert(RNA_property_array_check(prop) != false);
 
 	if ((idprop = rna_idproperty_check(&prop, ptr))) {
-		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
 		if (prop->arraydimension == 0)
 			IDP_Int(idprop) = values[0];
 		else
@@ -2297,7 +2297,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
 	BLI_assert(RNA_property_array_check(prop) != false);
 
 	if ((idprop = rna_idproperty_check(&prop, ptr))) {
-		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
 		if (prop->arraydimension == 0)
 			values[0] = RNA_property_float_get(ptr, prop);
 		else if (idprop->subtype == IDP_FLOAT) {
@@ -2392,7 +2392,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
 	BLI_assert(RNA_property_array_check(prop) != false);
 
 	if ((idprop = rna_idproperty_check(&prop, ptr))) {
-		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop));
+		BLI_assert(idprop->len == RNA_property_array_length(ptr, prop) || (prop->flag & PROP_IDPROPERTY));
 		if (prop->arraydimension == 0) {
 			if (idprop->type == IDP_FLOAT)
 				IDP_Float(idprop) = values[0];
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 408f99bd96ac6f511a10bc5e418f43d2aeda30bc..a55be8e285facb2cd3523ea8e4ca2dc2c178b767 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -62,6 +62,7 @@
 #include "ED_node.h"
 
 #include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
 
 static int rna_CurveMapping_curves_length(PointerRNA *ptr)
 {
@@ -609,10 +610,24 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain)
 			}
 
 			if (seq_found) {
+				if (seq->anim) {
+					IMB_free_anim(seq->anim);
+					seq->anim = NULL;
+				}
+
 				BKE_sequence_invalidate_cache(scene, seq);
 				BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
 			}
 			else {
+				SEQ_BEGIN(scene->ed, seq);
+				{
+					if (seq->anim) {
+						IMB_free_anim(seq->anim);
+						seq->anim = NULL;
+					}
+				}
+				SEQ_END;
+
 				BKE_sequencer_cache_cleanup();
 				BKE_sequencer_preprocessed_cache_cleanup();
 			}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 31e87f44a6a7dd4a2d46f6ee4e7efc8277d15356..f6f133c5114aee5bf8036ccfe35288266582f69a 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -475,7 +475,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, Rep
 	if (particle_no < totpart) {
 
 		/* get uvco & mcol */
-		num = particle->num_dmcache;
+		num = (ELEM(particle->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ?
+		          particle->num : particle->num_dmcache;
 
 		if (num == DMCACHE_NOTFOUND)
 			if (particle->num < modifier->dm->getNumTessFaces(modifier->dm))
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 479f70531e5abd6f7c623ce636b3eb95b860651e..ae0841b4e28e0d800e272670f03b6f86df658421 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -821,7 +821,9 @@ static EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA
 	    (ptr->type == &RNA_EnumProperty) ||
 	    (C == NULL))
 	{
-		return eprop->item;
+		if (eprop->item) {
+			return eprop->item;
+		}
 	}
 
 	return eprop->itemf(C, ptr, prop, r_free);
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 16f51bdd34f2f649394ab31a9f876eb12e17e6bf..142e5cadfd1a1a7f0a9a87e8ea31247aefd2b4e8 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -1515,7 +1515,7 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis
 
 	ret = PyTuple_New(2);
 	PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
-	PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_width));
+	PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_height));
 	return ret;
 }
 
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 977c30ff20a2c5b2ed2caef22f1b0ae41ebbd9f6..59a2a0d78fc3911d6cc631446b1cc20d869253dd 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -981,6 +981,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
 	int a, vdone = false, result = BAKE_RESULT_OK;
 	bool use_mask = false;
 	bool use_displacement_buffer = false;
+	bool do_manage = BKE_scene_check_color_management_enabled(re->scene);
 	
 	re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
 	
@@ -1040,6 +1041,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
 		}
 		handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC);
 		handles[a].ssamp.shi[0].thread = a;
+		handles[a].ssamp.shi[0].do_manage = do_manage;
 		handles[a].ssamp.tot = 1;
 
 		handles[a].type = type;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 0d09fa0401e070e44ea79cf8f460f85b8fd923dc..7d662f8f338d950d0e718f711f8701b7bffdb16c 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -5873,7 +5873,9 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
 	re->lay= lay;
 
 	/* renderdata setup and exceptions */
-	re->r= scene->r;
+	BLI_freelistN(&re->r.layers);
+	re->r = scene->r;
+	BLI_duplicatelist(&re->r.layers, &scene->r.layers);
 	
 	RE_init_threadcount(re);
 	
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 74768f925f8a0047a4e5c8344a1a57c0cad9b8b9..4bf65879ad615f175115d8cc0364c07a93a0e1fb 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1413,7 +1413,6 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
 
 	if (op->type->flag & OPTYPE_MACRO) {
 		for (op = op->macro.first; op; op = op->next) {
-			uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
 			uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
 		}
 	}
@@ -1816,14 +1815,14 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
 
 	/* label for 'a' bugfix releases, or 'Release Candidate 1'...
 	 *  avoids recreating splash for version updates */
-	if (false) {
+	if (true) {
 		/* placed after the version number in the image,
 		 * placing y is tricky to match baseline */
 		int x = 260 - (2 * UI_DPI_WINDOW_FAC);
 		int y = 242 + (4 * UI_DPI_WINDOW_FAC);
 		int w = 240;
 
-		const char *version_suffix = "Release Candidate";
+		const char *version_suffix = "a";
 
 
 		/* hack to have text draw 'text_sel' */
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 6a2ef471be0f69978feda93ec0964f1d326deb7a..9fa64bf65b3cd3f0124de5c2ce0957a8f64fb6fc 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -373,15 +373,20 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win)
 		if (win->eventstate == NULL)
 			win->eventstate = MEM_callocN(sizeof(wmEvent), "window event state");
 		
+#ifdef __APPLE__
+		/* set the state here, else OSX would nor recignize changed screen resolution */
+		GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
+#endif
 		/* store actual window size in blender window */
 		bounds = GHOST_GetClientBounds(win->ghostwin);
 		win->sizex = GHOST_GetWidthRectangle(bounds);
 		win->sizey = GHOST_GetHeightRectangle(bounds);
 		GHOST_DisposeRectangle(bounds);
-
-		/* set the state */
+		
+#ifndef __APPLE__
+		/* set the state here, so minimized state comes up correct on windows */
 		GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
-
+#endif
 		/* until screens get drawn, make it nice gray */
 		glClearColor(0.55, 0.55, 0.55, 0.0);
 		/* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 0ec54412485bf067ce6b823af26e4289377d5928..365bce34a60762cbcbef4726b9916d0ba0c5118b 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -938,11 +938,12 @@ static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace
 	// this way only one KX_BlenderMaterial object has to exist per bucket
 	bool bucketCreated; 
 	RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
-	if (bucketCreated) {
-		// this is needed to free up memory afterwards
-		converter->RegisterPolyMaterial(polymat);
-		converter->RegisterBlenderMaterial(bl_mat);
-	}
+
+	// this is needed to free up memory afterwards.
+	// the converter will also prevent duplicates from being registered,
+	// so just register everything.
+	converter->RegisterPolyMaterial(polymat);
+	converter->RegisterBlenderMaterial(bl_mat);
 
 	return bucket;
 }
diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp
index be85d89775fbb487638ba897d2421b2174152a6d..75beb5d0e0e7ac1325d3f90d7f8ed2e81b2d887b 100644
--- a/source/gameengine/Converter/BlenderWorldInfo.cpp
+++ b/source/gameengine/Converter/BlenderWorldInfo.cpp
@@ -61,6 +61,7 @@
 #include "BLI_math.h"
 
 #include "BKE_global.h"
+#include "BKE_scene.h"
 /* end of blender include block */
 
 
@@ -86,7 +87,7 @@ BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World *ble
 		copy_v3_v3(m_backgroundcolor, &blenderworld->horr);
 		copy_v3_v3(m_ambientcolor, &blenderworld->ambr);
 
-		if (blenderscene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+		if (BKE_scene_check_color_management_enabled(blenderscene)) {
 			linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor);
 			linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor);
 			linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor);
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index c0c28d15ad31374ad4f78ef184f725f181ccad30..854e9fe732782669f002f830bb21aa2d98310eac 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -233,8 +233,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
 	Scene *sce;
 
 	/**
-	 * Find the specified scene by name, or the first
-	 * scene if nothing matches (shouldn't happen).
+	 * Find the specified scene by name, or NULL if nothing matches.
 	 */
 	if ((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
 		return sce;
@@ -246,7 +245,7 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
 			return sce;
 	}
 
-	return (Scene*)m_maggie->scene.first;
+	return NULL;
 
 }
 
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 3aa5a9f4f0ef35ee869b8c6f1078d571c2002e30..e6b22420d906af53c51dcc617afcd2039bd8970c 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -1702,6 +1702,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading)
 KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
 {
 	Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
+	if (!scene)
+		return NULL;
 	return CreateScene(scene);
 }
 
@@ -1717,8 +1719,12 @@ void KX_KetsjiEngine::AddScheduledScenes()
 		{
 			STR_String scenename = *scenenameit;
 			KX_Scene* tmpscene = CreateScene(scenename);
-			m_scenes.push_back(tmpscene);
-			PostProcessScene(tmpscene);
+			if (tmpscene) {
+				m_scenes.push_back(tmpscene);
+				PostProcessScene(tmpscene);
+			} else {
+				printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr());
+			}
 		}
 		m_addingOverlayScenes.clear();
 	}
@@ -1731,9 +1737,12 @@ void KX_KetsjiEngine::AddScheduledScenes()
 		{
 			STR_String scenename = *scenenameit;
 			KX_Scene* tmpscene = CreateScene(scenename);
-			m_scenes.insert(m_scenes.begin(),tmpscene);
-			PostProcessScene(tmpscene);
-
+			if (tmpscene) {
+				m_scenes.insert(m_scenes.begin(),tmpscene);
+				PostProcessScene(tmpscene);
+			} else {
+				printf("warning: scene %s could not be found, not added!\n",scenename.ReadPtr());
+			}
 		}
 		m_addingBackgroundScenes.clear();
 	}
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index e85b57f17695d3473ccdd58ef36882f4b7dd3db1..abbe65738d476b39080a13cc3e95e8de30204466 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -395,10 +395,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 		return;
 
 	const int *viewport = canvas->GetViewPort();
-	RAS_Rect rect = canvas->GetWindowArea();
-	int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1;
 
-	if (texturewidth != rect_width || textureheight != rect_height)
+	if (texturewidth != viewport[2] || textureheight != viewport[3])
 	{
 		UpdateOffsetMatrix(canvas);
 		UpdateCanvasTextureCoord(viewport);
@@ -414,22 +412,22 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 	if (need_depth) {
 		glActiveTextureARB(GL_TEXTURE1);
 		glBindTexture(GL_TEXTURE_2D, texname[1]);
-		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
+		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], viewport[2], viewport[3], 0);
 	}
 	
 	if (need_luminance) {
 		glActiveTextureARB(GL_TEXTURE2);
 		glBindTexture(GL_TEXTURE_2D, texname[2]);
-		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0);
+		glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1], viewport[2], viewport[3], 0);
 	}
 
 	// reverting to texunit 0, without this we get bug [#28462]
 	glActiveTextureARB(GL_TEXTURE0);
-	canvas->SetViewPort(0, 0, rect_width-1, rect_height-1);
 
 	// We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport,
 	// but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen. 
 	RAS_Rect scissor_rect = canvas->GetDisplayArea();
+
 	glScissor(scissor_rect.GetLeft() + viewport[0],
 	          scissor_rect.GetBottom() + viewport[1],
 	          scissor_rect.GetWidth() + 1,
@@ -459,7 +457,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 
 			glActiveTextureARB(GL_TEXTURE0);
 			glBindTexture(GL_TEXTURE_2D, texname[0]);
-			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
+			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], viewport[2], viewport[3], 0); // Don't use texturewidth and textureheight in case we don't have NPOT support
 			glClear(GL_COLOR_BUFFER_BIT);
 
 			glBegin(GL_QUADS);
@@ -473,8 +471,6 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
 	}
 
 	glEnable(GL_DEPTH_TEST);
-	//We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517]
-	canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1);
 	EndShaderProgram();
 	glPopMatrix();
 	glMatrixMode(GL_MODELVIEW);