diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py
index 32b6597b5d55eda149f52615642cd376808585cf..02e5dbb7f8fa5438630388b93bdeac3c55ef9c81 100644
--- a/config/win32-vc-config.py
+++ b/config/win32-vc-config.py
@@ -157,7 +157,7 @@ REL_CCFLAGS = ['-O2', '-DNDEBUG']
 C_WARN = []
 CC_WARN = []
 
-LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid'
+LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid'
 
 PLATFORM_LINKFLAGS = '''
                         /SUBSYSTEM:CONSOLE 
diff --git a/release/windows/installer/00.sconsblender.nsi b/release/windows/installer/00.sconsblender.nsi
index c4e504a5bff3c32ba0b831067c3f60d8a8399c2d..338075c1b18e64bd6fa7e1b333d07b11edc99b69 100644
--- a/release/windows/installer/00.sconsblender.nsi
+++ b/release/windows/installer/00.sconsblender.nsi
@@ -32,7 +32,7 @@ Name "Blender VERSION"
     
 !insertmacro MUI_PAGE_DIRECTORY
 Page custom DataLocation DataLocationOnLeave
-Page custom AppDataChoice AppDataChoiceOnLeave
+;Page custom AppDataChoice AppDataChoiceOnLeave
 Page custom PreMigrateUserSettings MigrateUserSettings
 !insertmacro MUI_PAGE_INSTFILES
 !insertmacro MUI_PAGE_FINISH
@@ -271,7 +271,9 @@ Function DataLocationOnLeave
 	StrCpy $SETUSERCONTEXT "false"
 	${NSD_GetState} $HWND_APPDATA $R0
 	${If} $R0 == "1"
-	  StrCpy $SETUSERCONTEXT "true"
+	  ; FIXME: disabled 'all users' until fully multi-user compatible
+	  ;StrCpy $SETUSERCONTEXT "true"
+	  Call SetWinXPPathCurrentUser
 	${Else}
 	  ${NSD_GetState} $HWND_INSTDIR $R0
 	  ${If} $R0 == "1"
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ab1bc5a2265be412d4ebea2c5fc2f0ea4ad2d9ed..4f901ba72163c688b84a243211260a29e657bebc 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1614,7 +1614,7 @@ static void give_parvert(Object *par, int nr, float *vec)
 			
 			for(eve= em->verts.first; eve; eve= eve->next) {
 				if(eve->keyindex==nr) {
-					memcpy(vec, eve->co, 12);
+					memcpy(vec, eve->co, sizeof(float)*3);
 					break;
 				}
 			}
@@ -1652,18 +1652,20 @@ static void give_parvert(Object *par, int nr, float *vec)
 		Curve *cu;
 		BPoint *bp;
 		BezTriple *bezt;
+		int found= 0;
 		
 		cu= par->data;
 		nu= cu->nurb.first;
 		if(par==G.obedit) nu= editNurb.first;
 		
 		count= 0;
-		while(nu) {
+		while(nu && !found) {
 			if((nu->type & 7)==CU_BEZIER) {
 				bezt= nu->bezt;
 				a= nu->pntsu;
 				while(a--) {
 					if(count==nr) {
+						found= 1;
 						VECCOPY(vec, bezt->vec[1]);
 						break;
 					}
@@ -1676,7 +1678,8 @@ static void give_parvert(Object *par, int nr, float *vec)
 				a= nu->pntsu*nu->pntsv;
 				while(a--) {
 					if(count==nr) {
-						memcpy(vec, bp->vec, 12);
+						found= 1;
+						memcpy(vec, bp->vec, sizeof(float)*3);
 						break;
 					}
 					count++;
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index c85849b5ed4be35af35c35c406011801e8ef005f..3610813f2dac1be4c7023eee39356e772bee759b 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -1166,6 +1166,7 @@ int BLI_convertstringcode(char *path, const char *basepath)
 		MEM_freeN(filepart);
 	}
 	
+	BLI_cleanup_file(NULL, tmp);
 	strcpy(path, tmp);
 	
 #ifdef WIN32
diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h
index 0d1e792eb1c079a38cb5937028e5e997d1466106..b353e7bb45cbc135683e804776679de4e99a4b18 100644
--- a/source/blender/include/BIF_editseq.h
+++ b/source/blender/include/BIF_editseq.h
@@ -92,8 +92,8 @@ start and end are from the start and fixed length of the sequence.
 int seq_tx_get_start(struct Sequence *seq);
 int seq_tx_get_end(struct Sequence *seq);
 
-int seq_tx_get_final_left(struct Sequence *seq);
-int seq_tx_get_final_right(struct Sequence *seq);
+int seq_tx_get_final_left(struct Sequence *seq, int metaclip);
+int seq_tx_get_final_right(struct Sequence *seq, int metaclip);
 
 void seq_tx_set_final_left(struct Sequence *seq, int i);
 void seq_tx_set_final_right(struct Sequence *seq, int i);
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 982a2f25df700c8d5ea131fe2e54b828365ae7c2..82adb1ac12af8ee302aac102034bf2f7739d0478 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -515,6 +515,7 @@ int handleNDofInput(NDofInput *n, unsigned short event, short val);
 
 int manageObjectSpace(int confirm, int set);
 int manageMeshSpace(int confirm, int set);
+int manageBoneSpace(int confirm, int set);
 
 /* Those two fill in mat and return non-zero on success */
 int createSpaceNormal(float mat[3][3], float normal[3]);
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 9b837f9f9886b013c393617c14f44eab892048ca..83f4e633fa1670303de53f430d3ebbe1e1eb7e18 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -688,18 +688,18 @@ static int calculate_structlens(int firststruct)
 						/* 4-8 aligned/ */
 						if(sizeof(void *) == 4) {
 							if (len % 4) {
-								printf("Align pointer error in struct: %s %s\n", types[structtype], cp);
+								printf("Align pointer error in struct (len4): %s %s\n", types[structtype], cp);
 								dna_error = 1;
 							}
 						} else {
 							if (len % 8) {
-								printf("Align pointer error in struct: %s %s\n", types[structtype], cp);
+								printf("Align pointer error in struct (len8): %s %s\n", types[structtype], cp);
 								dna_error = 1;
 							}
 						}
 
 						if (alphalen % 8) {
-							printf("Align pointer error in struct: %s %s\n", types[structtype],cp);
+							printf("Align pointer error in struct (alphalen8): %s %s\n", types[structtype],cp);
 							dna_error = 1;
 						}
 
@@ -748,13 +748,13 @@ static int calculate_structlens(int firststruct)
 					// has_pointer is set or alphalen != len
 					if (has_pointer || alphalen != len) {
 						if (alphalen % 8) {
-							printf("Sizeerror in struct: %s (add %d bytes)\n", types[structtype], alphalen%8);
+							printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8);
 							dna_error = 1;
 						}
 					}
 					
 					if(len % 4) {
-						printf("Sizeerror in struct: %s (add %d bytes)\n", types[structtype], len%4);
+						printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4);
 						dna_error = 1;
 					}
 					
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index 3d4546613be47d74481bba65f76ce8a29d472e6c..047a035fb8b4c5d6ddb78e24593e21e38f900ba4 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -613,6 +613,8 @@ static void exit_pydraw( SpaceScript * sc, short err )
 		PyErr_Print(  );
 		script->flags = 0;	/* mark script struct for deletion */
 		SCRIPT_SET_NULL(script);
+		script->scriptname[0] = '\0';
+		script->scriptarg[0] = '\0';
 		error_pyscript();
 		scrarea_queue_redraw( sc->area );
 	}
diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c
index 92529023b7e44afeb186027dbb3489f5585cf307..792b23315084c5ea648733f84782d1c9b8bbf943 100644
--- a/source/blender/python/api2_2x/Node.c
+++ b/source/blender/python/api2_2x/Node.c
@@ -848,7 +848,7 @@ static int Sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObj
 
 	if (PyInt_Check(pyidx)) {
 		idx = (int)PyInt_AsLong(pyidx);
-		if (idx < 0 || idx >= Sockinmap_len(self))
+		if (idx < 0 || idx >= Sockoutmap_len(self))
 			return EXPP_ReturnIntError(PyExc_IndexError, "index out of range");
 	}
 	else if (PyString_Check(pyidx)) {
diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c
index 7ef351b112751349d96ba610ceb716c927829ae2..eba951b88133b434ce0946e226fba18ae65ea9bb 100644
--- a/source/blender/python/api2_2x/Scene.c
+++ b/source/blender/python/api2_2x/Scene.c
@@ -1355,16 +1355,29 @@ static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
 		for (base= scene->base.first; base && i!=index; base= base->next, index++) {}
 	/* selected */
 	else if (self->mode==EXPP_OBSEQ_SELECTED) {
-		for (base= scene->base.first; base && i!=index; base= base->next)
-			if (base->flag & SELECT)
-				index++;
+		for (base= scene->base.first; base; base= base->next) {
+			if (base->flag & SELECT) {
+				if (i==index) {
+					break;
+				} else {
+					index++;
+				}
+			}
+		}
 	}
 	/* context */
 	else if (self->mode==EXPP_OBSEQ_CONTEXT) {
-		if (G.vd)
-			for (base= scene->base.first; base && i!=index; base= base->next)
-				if TESTBASE(base)
-					index++;
+		if (G.vd) {
+			for (base= scene->base.first; base; base= base->next) {
+				if (TESTBASE(base)) {
+					if (i==index) {
+						break;
+					} else {
+						index++;
+					}
+				}
+			}
+		}
 	}
 	
 	if (!(base))
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index f54c2cd4e3bf595f0788340e38b4c904b036d3b6..bfad069f9434ad88ea467e02b8f48875ec510391 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -478,9 +478,11 @@ PyObject *RenderData_Render( BPy_RenderData * self )
 	}
 
 	else { /* background mode (blender -b file.blend -P script) */
-		Render *re= RE_NewRender("Render");
+		Render *re= RE_NewRender(G.scene->id.name);
 
-		int end_frame = G.scene->r.efra; /* is of type short currently */
+
+
+		int end_frame = G.scene->r.efra;
 
 		if (G.scene != self->scene)
 			return EXPP_ReturnPyObjError (PyExc_RuntimeError,
@@ -490,7 +492,7 @@ PyObject *RenderData_Render( BPy_RenderData * self )
 
 		RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
 
-		G.scene->r.efra = (short)end_frame;
+		G.scene->r.efra = end_frame;
 	}
 
 	Py_RETURN_NONE;
@@ -571,7 +573,7 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self )
 		set_scene( oldsce );
 	}
 	else { /* background mode (blender -b file.blend -P script) */
-		Render *re= RE_NewRender("Render");
+		Render *re= RE_NewRender(G.scene->id.name);
 		
 		if (G.scene != self->scene)
 			return EXPP_ReturnPyObjError (PyExc_RuntimeError,
diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h
index aec1c69b3dca9cfce1689cf3d0f8bbd8f927145e..8f429f7dd906f9a0eae9be6b5dbf74f981e7f83d 100644
--- a/source/blender/render/extern/include/RE_raytrace.h
+++ b/source/blender/render/extern/include/RE_raytrace.h
@@ -70,7 +70,7 @@ typedef struct Isect {
 	int ob_last;
 
 	short isect;			/* which half of quad */
-	short mode;				/* RE_RAYSHADOW, RE_RAYMIRROR, RE_RAYSHADOW_TRA */
+	short mode;				/* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */
 	int lay;				/* -1 default, set for layer lamps */
 
 	/* only used externally */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index fb699f5b38273e7f085c3ff1b279604f4106e313..ebb52c491323d2f71141f43dd9781004c3c79b96 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -993,6 +993,7 @@ RenderStats *RE_GetStats(Render *re)
 	return &re->i;
 }
 
+/* Note, when rendering from a scene, ALWAYS use G.scene->id.name, else compositing wont work */
 Render *RE_NewRender(const char *name)
 {
 	Render *re;
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 8fd07001bd114aca12e2d5787fec357ef4074b66..1155d2ea81770585ae378545482eb3d3e1555740 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -1473,14 +1473,15 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
 	int tot;
 	float *vec;
 	
-	if(resol>16) resol= 16;
-	
 	tot= 2*resol*resol;
 
 	if (type & WO_AORNDSMP) {
-		static float sphere[2*3*256];
+		float *sphere;
 		int a;
 		
+		// always returns table
+		sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
+
 		/* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */
 		vec= sphere;
 		for (a=0; a<tot; a++, vec+=3) {
@@ -1495,7 +1496,8 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
 		float ang, *vec1;
 		int a;
 		
-		sphere= threadsafe_table_sphere(1, thread, xs, ys, tot);	// returns table if xs and ys were equal to last call
+		// returns table if xs and ys were equal to last call
+		sphere= threadsafe_table_sphere(1, thread, xs, ys, tot);
 		if(sphere==NULL) {
 			sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
 			
@@ -1663,7 +1665,7 @@ void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
 	float *vec, *nrm, div, bias, sh=0.0f;
 	float maxdist = R.wrld.aodist;
 	float dxyview[3];
-	int j= -1, tot, actual=0, skyadded=0, aocolor;
+	int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp;
 	
 	isec.faceorig= (RayFace*)shi->vlr;
 	isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
@@ -1690,14 +1692,16 @@ void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
 	if(shi->mat->mode & MA_ONLYSHADOW)
 		aocolor= WO_AOPLAIN;
 	
-	vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
+	if(resol>32) resol= 32;
+	
+	vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys);
 	
 	// warning: since we use full sphere now, and dotproduct is below, we do twice as much
-	tot= 2*R.wrld.aosamp*R.wrld.aosamp;
+	tot= 2*resol*resol;
 
 	if(aocolor == WO_AOSKYTEX) {
-		dxyview[0]= 1.0f/(float)R.wrld.aosamp;
-		dxyview[1]= 1.0f/(float)R.wrld.aosamp;
+		dxyview[0]= 1.0f/(float)resol;
+		dxyview[1]= 1.0f/(float)resol;
 		dxyview[2]= 0.0f;
 	}
 	
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 0b042fc542f853f730a9b860bf97f74022b1d597..0bb9e5f9e5532f24685a9c861961b9d6f53a289f 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -2922,7 +2922,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 	float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3];
 	int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0;
 	int path_possible=0, keys_possible=0, draw_keys=0, totchild=0;
-	int select=ob->flag&SELECT;
+	int select=ob->flag&SELECT, create_cdata=0;
 	GLint polygonmode[2];
 	char val[32];
 
@@ -2976,8 +2976,10 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 
 	if(select)
 		cpack(0xFFFFFF);
-	else if((ma) && (part->draw&PART_DRAW_MAT_COL))
+	else if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
 		glColor3f(ma->r,ma->g,ma->b);
+		create_cdata = 1;
+	}
 	else
 		cpack(0);
 
@@ -3085,19 +3087,25 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 		if(draw_as!=PART_DRAW_CIRC){
 			switch(draw_as){
 				case PART_DRAW_AXIS:
-					cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata");
-					/* no break! */
 				case PART_DRAW_CROSS:
+					if(draw_as!=PART_DRAW_CROSS || create_cdata)
+						cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata");
 					vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata");
 					break;
 				case PART_DRAW_LINE:
+					if(create_cdata)
+						cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata");
 					vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata");
 					break;
 				case PART_DRAW_BB:
+					if(create_cdata)
+						cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata");
 					vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
 					ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
 					break;
 				default:
+					if(create_cdata)
+						cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata");
 					vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata");
 			}
 		}
@@ -3122,9 +3130,17 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 
 				pa_time=(cfra-pa->time)/pa->lifetime;
 
-				if((part->flag&PART_ABS_TIME)==0 && part->ipo){
-					calc_ipo(part->ipo, 100*pa_time);
-					execute_ipo((ID *)part, part->ipo);
+				if((part->flag&PART_ABS_TIME)==0){				
+					if(ma && ma->ipo){
+						/* correction for lifetime */
+						calc_ipo(ma->ipo, 100.0f*pa_time);
+						execute_ipo((ID *)ma, ma->ipo);
+					}
+					if(part->ipo) {
+						/* correction for lifetime */
+						calc_ipo(part->ipo, 100*pa_time);
+						execute_ipo((ID *)part, part->ipo);
+					}
 				}
 
 				pa_size=pa->size;
@@ -3141,9 +3157,17 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 
 				pa_time=psys_get_child_time(psys,cpa,cfra);
 
-				if((part->flag&PART_ABS_TIME)==0 && part->ipo){
-					calc_ipo(part->ipo, 100*pa_time);
-					execute_ipo((ID *)part, part->ipo);
+				if((part->flag&PART_ABS_TIME)==0) {
+					if(ma && ma->ipo){
+						/* correction for lifetime */
+						calc_ipo(ma->ipo, 100.0f*pa_time);
+						execute_ipo((ID *)ma, ma->ipo);
+					}
+					if(part->ipo) {
+						/* correction for lifetime */
+						calc_ipo(part->ipo, 100*pa_time);
+						execute_ipo((ID *)part, part->ipo);
+					}
 				}
 
 				pa_size=psys_get_child_size(psys,cpa,cfra,0);
@@ -3181,6 +3205,12 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 
 					switch(draw_as){
 						case PART_DRAW_DOT:
+							if(cd) {
+								cd[0]=ma->r;
+								cd[1]=ma->g;
+								cd[2]=ma->b;
+								cd+=3;
+							}
 							if(vd){
 								VECCOPY(vd,state.co) vd+=3;
 							}
@@ -3201,7 +3231,15 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 
 								VECCOPY(vec2,state.co);
 							}
-							else VECSUB(vec2,state.co,vec);
+							else {
+								if(cd) {
+									cd[0]=cd[3]=cd[6]=cd[9]=cd[12]=cd[15]=ma->r;
+									cd[1]=cd[4]=cd[7]=cd[10]=cd[13]=cd[16]=ma->g;
+									cd[2]=cd[5]=cd[8]=cd[11]=cd[14]=cd[17]=ma->b;
+									cd+=18;
+								}
+								VECSUB(vec2,state.co,vec);
+							}
 
 							VECADD(vec,state.co,vec);
 							VECCOPY(vd,vec); vd+=3;
@@ -3239,11 +3277,25 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 								VecMulf(vec,VecLength(state.vel));
 							VECADDFAC(vd,state.co,vec,-part->draw_line[0]); vd+=3;
 							VECADDFAC(vd,state.co,vec,part->draw_line[1]); vd+=3;
+							if(cd) {
+								cd[0]=cd[3]=ma->r;
+								cd[1]=cd[4]=ma->g;
+								cd[2]=cd[5]=ma->b;
+								cd+=3;
+							}
 							break;
 						case PART_DRAW_CIRC:
+							if(create_cdata)
+								glColor3f(ma->r,ma->g,ma->b);
 							drawcircball(GL_LINE_LOOP, state.co, pixsize, imat);
 							break;
 						case PART_DRAW_BB:
+							if(cd) {
+								cd[0]=cd[3]=cd[6]=cd[9]=ma->r;
+								cd[1]=cd[4]=cd[7]=cd[10]=ma->g;
+								cd[2]=cd[5]=cd[8]=cd[11]=ma->b;
+								cd+=12;
+							}
 							if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){
 								VECCOPY(xvec,bb_ob->obmat[0]);
 								Normalize(xvec);
@@ -3439,13 +3491,14 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
 					glDisable(GL_LIGHTING);
 				}
 
+				if(cdata){
+					glEnableClientState(GL_COLOR_ARRAY);
+					glColorPointer(3, GL_FLOAT, 0, cdata);
+				}
+
 				switch(draw_as){
 					case PART_DRAW_AXIS:
 					case PART_DRAW_CROSS:
-						if(cdata){
-							glEnableClientState(GL_COLOR_ARRAY);
-							glColorPointer(3, GL_FLOAT, 0, cdata);
-						}
 						glDrawArrays(GL_LINES, 0, 6*totpoint);
 						break;
 					case PART_DRAW_LINE:
diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c
index e979f6e16fcc910c0199673a03e9c33ff33bf157..e554b91dd52a03bb400bdb845ebf57b3c16313b0 100644
--- a/source/blender/src/drawseq.c
+++ b/source/blender/src/drawseq.c
@@ -691,7 +691,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq, int outli
 	
 	/* draw the main strip body */
 	if (is_single_image) /* single image */
-		draw_shadedstrip(seq, col, seq_tx_get_final_left(seq), y1, seq_tx_get_final_right(seq), y2);
+		draw_shadedstrip(seq, col, seq_tx_get_final_left(seq, 0), y1, seq_tx_get_final_right(seq, 0), y2);
 	else /* normal operation */
 		draw_shadedstrip(seq, col, x1, y1, x2, y2);
 	
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 52e0d3d6f05c794e652ed157c301fe29caacd496..e83ecb1396005ab3273e30b244d13ba421bbfa96 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -3732,18 +3732,22 @@ int play_anim(int mode)
 					else viewmove(0);
 				}
 			} else if (event==WHEELDOWNMOUSE || (val && event==PADMINUS)) { /* copied from persptoetsen */
-				/* this min and max is also in viewmove() */
-				if(G.vd->persp==V3D_CAMOB) {
-					G.vd->camzoom-= 10;
-					if(G.vd->camzoom<-30) G.vd->camzoom= -30;
+				if (G.vd) { /* when using the sequencer this can be NULL */
+					/* this min and max is also in viewmove() */ 
+					if(G.vd->persp==V3D_CAMOB) {
+						G.vd->camzoom-= 10;
+						if(G.vd->camzoom<-30) G.vd->camzoom= -30;
+					}
+					else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
 				}
-				else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
 			} else if (event==WHEELUPMOUSE || (val && event==PADPLUSKEY)) { /* copied from persptoetsen */
-				if(G.vd->persp==V3D_CAMOB) {
-					G.vd->camzoom+= 10;
-					if(G.vd->camzoom>300) G.vd->camzoom= 300;
+				if (G.vd) {
+					if(G.vd->persp==V3D_CAMOB) {
+						G.vd->camzoom+= 10;
+						if(G.vd->camzoom>300) G.vd->camzoom= 300;
+					}
+					else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
 				}
-				else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
 			} else if(event==MKEY) {
 				if(val) add_marker(CFRA-1);
 			}
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index c166a9df7629b38871d2c9d5fe0baa77cf132e6a..39f93510358318ff5565e9357e6b06e197453ace 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -2396,6 +2396,7 @@ void fill_bones_armature(void)
 	else if (count == 2) {
 		EditBonePoint *ebp, *ebp2;
 		float head[3], tail[3];
+		short headtail = 0;
 		
 		/* check that the points don't belong to the same bone */
 		ebp= (EditBonePoint *)points.first;
@@ -2420,7 +2421,7 @@ void fill_bones_armature(void)
 			float distA, distB;
 			
 			/* get cursor location */
-			VECCOPY (curs, give_cursor());	
+			VECCOPY(curs, give_cursor());	
 			
 			Mat4Invert(G.obedit->imat, G.obedit->obmat);
 			Mat4MulVecfl(G.obedit->imat, curs);
@@ -2432,26 +2433,47 @@ void fill_bones_armature(void)
 			distB= VecLength(vecB);
 			
 			/* compare distances - closer one therefore acts as direction for bone to go */
-			if (distA < distB) {
-				VECCOPY(head, ebp2->vec);
-				VECCOPY(tail, ebp->vec);
-			}
-			else {
-				VECCOPY(head, ebp->vec);
-				VECCOPY(tail, ebp2->vec);
-			}
+			headtail= (distA < distB) ? 2 : 1;
 		}
 		else if (ebp->head_owner) {
+			headtail = 1;
+		}
+		else if (ebp2->head_owner) {
+			headtail = 2;
+		}
+		
+		/* assign head/tail combinations */
+		if (headtail == 2) {
 			VECCOPY(head, ebp->vec);
 			VECCOPY(tail, ebp2->vec);
 		}
-		else if (ebp2->head_owner) {
+		else if (headtail == 1) {
 			VECCOPY(head, ebp2->vec);
 			VECCOPY(tail, ebp->vec);
 		}
 		
-		/* add new bone */
-		newbone= add_points_bone(head, tail);
+		/* add new bone and parent it to the appropriate end */
+		if (headtail) {
+			newbone= add_points_bone(head, tail);
+			
+			/* do parenting (will need to set connected flag too) */
+			if (headtail == 2) {
+				/* ebp tail or head - tail gets priority */
+				if (ebp->tail_owner)
+					newbone->parent= ebp->tail_owner;
+				else
+					newbone->parent= ebp->head_owner;
+			}
+			else {
+				/* ebp2 tail or head - tail gets priority */
+				if (ebp2->tail_owner)
+					newbone->parent= ebp2->tail_owner;
+				else
+					newbone->parent= ebp2->head_owner;
+			}
+			
+			newbone->flag |= BONE_CONNECTED;
+		}
 	}
 	else {
 		// FIXME.. figure out a method for multiple bones
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index bb706f1aa3fe46840f4aad0a0d88762a6cd0a8c6..fb0fac4489d9772eadb7769a831f5195fd217a6c 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -184,13 +184,24 @@ int seq_tx_get_end(Sequence *seq)
 	return seq->start+seq->len;
 }
 
-int seq_tx_get_final_left(Sequence *seq)
+int seq_tx_get_final_left(Sequence *seq, int metaclip)
 {
-	return (seq->start - seq->startstill) + seq->startofs;
+	if (metaclip && seq->tmp) {
+		/* return the range clipped by the parents range */
+		return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) );
+	} else {
+		return (seq->start - seq->startstill) + seq->startofs;
+	}
+	
 }
-int  seq_tx_get_final_right(Sequence *seq)
+int seq_tx_get_final_right(Sequence *seq, int metaclip)
 {
-	return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
+	if (metaclip && seq->tmp) {
+		/* return the range clipped by the parents range */
+		return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) );
+	} else {
+		return ((seq->start+seq->len) + seq->endstill) - seq->endofs;	
+	}
 }
 
 void seq_tx_set_final_left(Sequence *seq, int val)
@@ -260,12 +271,12 @@ static void fix_single_image_seq(Sequence *seq)
 	
 	/* make sure the image is always at the start since there is only one,
 	   adjusting its start should be ok */
-	left = seq_tx_get_final_left(seq);
+	left = seq_tx_get_final_left(seq, 0);
 	start = seq->start;
 	if (start != left) {
 		offset = left - start;
-		seq_tx_set_final_left( seq, seq_tx_get_final_left(seq) - offset );
-		seq_tx_set_final_right( seq, seq_tx_get_final_right(seq) - offset );
+		seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset );
+		seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset );
 		seq->start += offset;
 	}
 }
@@ -2927,34 +2938,34 @@ static int seq_get_snaplimit(void)
 static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
 {
 	if(leftflag) {
-		if (seq_tx_get_final_left(seq) >= seq_tx_get_final_right(seq)) {
-			seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1);
+		if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
+			seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1);
 		}
 		
 		if (check_single_seq(seq)==0) {
-			if (seq_tx_get_final_left(seq) >= seq_tx_get_end(seq)) {
+			if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
 				seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
 			}
 			
 			/* dosnt work now - TODO */
 			/*
-			if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq)) {
+			if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
 				int ofs;
-				ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq);
+				ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
 				seq->start -= ofs;
-				seq_tx_set_final_left(seq, seq_tx_get_final_left(seq) + ofs );
+				seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs );
 			}*/
 			
 		}
 	}
 	
 	if(rightflag) {
-		if (seq_tx_get_final_right(seq) <=  seq_tx_get_final_left(seq)) {
-			seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1);
+		if (seq_tx_get_final_right(seq, 0) <=  seq_tx_get_final_left(seq, 0)) {
+			seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1);
 		}
 									
 		if (check_single_seq(seq)==0) {
-			if (seq_tx_get_final_right(seq) <= seq_tx_get_start(seq)) {
+			if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
 				seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
 			}
 		}
@@ -3033,9 +3044,24 @@ void transform_seq(int mode, int context)
 		for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
 			if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) 
 				totstrip++;
+			/* only needed for extend but can set here anyway since were alredy looping */
+			seq->tmp= NULL;
 		}
 	}
 	
+	/* for extending we need the metastrip clipped left/right values, set the metastrips as parents in seq->tmp */
+	if (mode=='e') {
+		Sequence *meta_seq;
+		for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+			if (seq->type == SEQ_META) {
+				for (meta_seq = seq->seqbase.first; meta_seq; meta_seq= meta_seq->next){
+					meta_seq->tmp= (void *)seq;
+				}
+			}
+		}
+	}
+	
+	
 	if (sseq->flag & SEQ_MARKER_TRANS) {
 		for(marker= G.scene->markers.first; marker; marker= marker->next) {
 			if(marker->flag & SELECT) totmark++;
@@ -3064,8 +3090,8 @@ void transform_seq(int mode, int context)
 			
 			/* for extend only */
 			if (mode=='e') {
-				ts->final_left = seq_tx_get_final_left(seq);
-				ts->final_right = seq_tx_get_final_right(seq);
+				ts->final_left = seq_tx_get_final_left(seq, 1);
+				ts->final_right = seq_tx_get_final_right(seq, 1);
 			}
 			ts++;
 		}
@@ -3151,9 +3177,9 @@ void transform_seq(int mode, int context)
 				snap_point_num=0;
 				if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */
 					if(seq_tx_check_left(last_seq))
-						snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq);
+						snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq, 0);
 					if(seq_tx_check_right(last_seq))
-						snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq);
+						snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq, 0);
 					
 				}
 				if (totstrip > 1) { /* selection bounds */
@@ -3163,9 +3189,9 @@ void transform_seq(int mode, int context)
 					for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
 						if(seq->flag & SELECT) {
 							if(seq_tx_check_left(seq))
-								bounds_left		= MIN2(bounds_left,	seq_tx_get_final_left(seq));
+								bounds_left		= MIN2(bounds_left,	seq_tx_get_final_left(seq, 0));
 							if(seq_tx_check_right(seq))
-								bounds_right	= MAX2(bounds_right,seq_tx_get_final_right(seq));
+								bounds_right	= MAX2(bounds_right,seq_tx_get_final_right(seq, 0));
 						}
 					}
 					
@@ -3214,13 +3240,13 @@ void transform_seq(int mode, int context)
 				if (snap_dist && last_seq && seq_tx_check_left(last_seq)) {
 					seq = find_next_prev_sequence(last_seq, 1, 0); /* left */
 					if(seq && !seq_tx_check_right(seq))
-						TESTSNAP(seq_tx_get_final_right(seq));
+						TESTSNAP(seq_tx_get_final_right(seq, 0));
 				}
 				
 				if (snap_dist && last_seq && seq_tx_check_right(last_seq)) {
 					seq = find_next_prev_sequence(last_seq, 2, 0); /* right */
 					if(seq && !seq_tx_check_left(seq))
-						TESTSNAP(seq_tx_get_final_left(seq));
+						TESTSNAP(seq_tx_get_final_left(seq, 0));
 				}
 
 #undef TESTSNAP
@@ -3242,20 +3268,23 @@ void transform_seq(int mode, int context)
 				for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
 					if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
 						int myofs;
+						/* flag, ignores lefsel/rightsel for nested strips */
+						int sel_flag = (seq->depth==0) ? seq->flag : seq->flag & ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
+						
 						// SEQ_DEBUG_INFO(seq);
 						
 						/* X Transformation */
-						if(seq->flag & SEQ_LEFTSEL) {
+						if((seq->depth==0) && (sel_flag & SEQ_LEFTSEL)) {
 							myofs = (ts->startofs - ts->startstill);
 							seq_tx_set_final_left(seq, ts->start + (myofs + ix));
 						}
-						if(seq->flag & SEQ_RIGHTSEL) {
+						if((seq->depth==0) && (sel_flag & SEQ_RIGHTSEL)) {
 							myofs = (ts->endstill - ts->endofs);
 							seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix));
 						}
-						transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
+						transform_grab_xlimits(seq, sel_flag & SEQ_LEFTSEL, sel_flag & SEQ_RIGHTSEL);
 						
-						if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
+						if( (sel_flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
 							if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
 
 							/* Y Transformation */
@@ -3300,8 +3329,8 @@ void transform_seq(int mode, int context)
 							
 							//SEQ_DEBUG_INFO(seq);
 							
-							final_left =	seq_tx_get_final_left(seq);
-							final_right =	seq_tx_get_final_right(seq);
+							final_left =	seq_tx_get_final_left(seq, 1);
+							final_right =	seq_tx_get_final_right(seq, 1);
 							
 							/* Only X Axis moving */
 							
@@ -3591,8 +3620,8 @@ void seq_separate_images(void)
 			BLI_remlink(ed->seqbasep, seq); 
 			if(seq->ipo) seq->ipo->id.us--;
 			
-			start_ofs = cfra = seq_tx_get_final_left(seq);
-			frame_end = seq_tx_get_final_right(seq);
+			start_ofs = cfra = seq_tx_get_final_left(seq, 0);
+			frame_end = seq_tx_get_final_right(seq, 0);
 			
 			while (cfra < frame_end) {
 				/* new seq */
diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c
index 9689ffdafebc76ec5a2dd8d9d20eb96c8658cc83..2ba5745b19b062e0630f3f5b47d9373c9aa3f31c 100644
--- a/source/blender/src/filesel.c
+++ b/source/blender/src/filesel.c
@@ -1591,7 +1591,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile)
 		BLI_del_slash(butname);
 		
 		if(sfile->type & FILE_UNIX) {
-			if (!BLI_exists(butname)) {
+			if (butname[0] != '\0' && !BLI_exists(butname)) {
 				if (okee("Makedir")) {
 					BLI_recurdir_fileops(butname);
 					if (!BLI_exists(butname)) parent(sfile);
diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c
index a7361a9ffca35b76c07b5902de74063a30413f21..8b9c89656fb9b7c8bbcaa430313a512ff212d8bf 100644
--- a/source/blender/src/fluidsim.c
+++ b/source/blender/src/fluidsim.c
@@ -481,6 +481,7 @@ void fluidsimBake(struct Object *ob)
 	struct Object *fsDomain = NULL;
 	FluidsimSettings *domainSettings;
 	struct Object *obit = NULL; /* object iterator */
+	Base *base;
 	int origFrame = G.scene->r.cfra;
 	char debugStrBuffer[256];
 	int dirExist = 0;
@@ -522,7 +523,7 @@ void fluidsimBake(struct Object *ob)
 	float *channelObjMove[256][3]; // object movments , 0=trans, 1=rot, 2=scale
 	float *channelObjInivel[256];    // initial velocities
 	float *channelObjActive[256];    // obj active channel
-
+	
 	if(getenv(strEnvName)) {
 		int dlevel = atoi(getenv(strEnvName));
 		elbeemSetDebugLevel(dlevel);
@@ -545,7 +546,6 @@ void fluidsimBake(struct Object *ob)
 
 	/* no object pointer, find in selected ones.. */
 	if(!ob) {
-		Base *base;
 		for(base=G.scene->base.first; base; base= base->next) {
 			if ( ((base)->flag & SELECT) 
 					// ignore layer setting for now? && ((base)->lay & G.vd->lay) 
@@ -561,8 +561,26 @@ void fluidsimBake(struct Object *ob)
 		if(!ob) return;
 	}
 
+	channelObjCount = 0;
+	for(base=G.scene->base.first; base; base= base->next) {
+		obit = base->object;
+		//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
+		if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && 
+				(obit->type==OB_MESH) &&
+				(obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) &&  // if has to match 3 places! // CHECKMATCH
+				(obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE) ) {
+			channelObjCount++;
+		}
+	}
+	
+	if (channelObjCount>=255) {
+		pupmenu("Fluidsim Bake Error%t|Cannot bake with more then 256 objects");
+		return;
+	}
+
 	/* check if there's another domain... */
-	for(obit= G.main->object.first; obit; obit= obit->id.next) {
+	for(base=G.scene->base.first; base; base= base->next) {
+		obit = base->object;
 		if((obit->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(obit->type==OB_MESH)) {
 			if(obit->fluidsimSettings->type == OB_FLUIDSIM_DOMAIN) {
 				if(obit != ob) {
@@ -605,7 +623,8 @@ void fluidsimBake(struct Object *ob)
 	
 	// check if theres any fluid
 	// abort baking if not...
-	for(obit= G.main->object.first; obit; obit= obit->id.next) {
+	for(base=G.scene->base.first; base; base= base->next) {
+		obit = base->object;
 		if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && 
 				(obit->type==OB_MESH) && (
 			  (obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) ||
@@ -749,7 +768,8 @@ void fluidsimBake(struct Object *ob)
 	
 	// init obj movement channels
 	channelObjCount=0;
-	for(obit= G.main->object.first; obit; obit= obit->id.next) {
+	for(base=G.scene->base.first; base; base= base->next) {
+		obit = base->object;
 		//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
 		if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && 
 				(obit->type==OB_MESH) &&
@@ -952,7 +972,8 @@ void fluidsimBake(struct Object *ob)
 		
 		// init objects
 		channelObjCount = 0;
-		for(obit= G.main->object.first; obit; obit= obit->id.next) {
+		for(base=G.scene->base.first; base; base= base->next) {
+			obit = base->object;
 			//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
 			if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&  // if has to match 3 places! // CHECKMATCH
 					(obit->type==OB_MESH) &&
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index e27e772edeed83934ecf5a87618c7fab69b3fe95..ac165d6aeb2fea6168c17921af14b069ff11c1cd 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -957,6 +957,12 @@ int *mesh_get_x_mirror_faces(Object *ob)
 		mirrormf.v3= mirrorverts[mf->v1];
 		mirrormf.v4= (mf->v4)? mirrorverts[mf->v4]: 0;
 
+		/* make sure v4 is not 0 if a quad */
+		if(mf->v4 && mirrormf.v4==0) {
+			SWAP(int, mirrormf.v1, mirrormf.v3);
+			SWAP(int, mirrormf.v2, mirrormf.v4);
+		}
+
 		hashmf= BLI_ghash_lookup(fhash, &mirrormf);
 		if(hashmf) {
 			mirrorfaces[a*2]= hashmf - mface;
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 4be525f494574eabdf25e1835b009146b1ebd831..dcebf6b75578351cd5231cecd1fa2f44b05a3fa2 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -1365,7 +1365,7 @@ static void createTransCurveVerts(TransInfo *t)
 						tail++;
 					}
 					if(		propmode ||
-							((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
+							((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
 							((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
 					  ) {
 						VECCOPY(td->iloc, bezt->vec[2]);
diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c
index 5c06aaea890be358e838a40330630542d67e3562..050360887b4d1f3a73d1ec0880d774b4805f2842 100644
--- a/source/blender/src/transform_manipulator.c
+++ b/source/blender/src/transform_manipulator.c
@@ -158,7 +158,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags)
 }
 
 /* for pose mode */
-static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *plane)
+static void stats_pose(View3D *v3d, bPoseChannel *pchan)
 {
 	Bone *bone= pchan->bone;
 	
@@ -166,9 +166,6 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *p
 		if (bone->flag & BONE_TRANSFORM) {
 			calc_tw_center(pchan->pose_head);
 			protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag);
-
-			VecAddf(normal, normal, pchan->pose_mat[2]);
-			VecAddf(plane, plane, pchan->pose_mat[1]);
 		}
 	}
 }
@@ -349,26 +346,24 @@ int calc_manipulator_stats(ScrArea *sa)
 		}
 	}
 	else if(ob && (ob->flag & OB_POSEMODE)) {
-		bArmature *arm= ob->data;
+		bArmature *arm = ob->data;
 		bPoseChannel *pchan;
 		int mode;
 		
 		if((ob->lay & G.vd->lay)==0) return 0;
 		
-		mode= Trans.mode;
-		Trans.mode= TFM_ROTATION;	// mislead counting bones... bah
+		mode = Trans.mode;
+		Trans.mode = TFM_ROTATION;	// mislead counting bones... bah
 		
 		/* count total, we use same method as transform will do */
 		Trans.total= 0;
 		count_bone_select(&Trans, arm, &arm->bonebase, 1);
-		totsel= Trans.total;
+		totsel = Trans.total;
 		if(totsel) {
 			/* use channels to get stats */
 			for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-				stats_pose(v3d, pchan, normal, plane);
+				stats_pose(v3d, pchan);
 			}
-			//VecMulf(normal, -1.0);
-			VecMulf(plane, -1.0);
 			
 			VecMulf(G.scene->twcent, 1.0f/(float)totsel);	// centroid!
 			Mat4MulVecfl(ob->obmat, G.scene->twcent);
@@ -376,7 +371,7 @@ int calc_manipulator_stats(ScrArea *sa)
 			Mat4MulVecfl(ob->obmat, G.scene->twmax);
 		}
 		/* restore, mode can be TFM_INIT */
-		Trans.mode= mode;
+		Trans.mode = mode;
 	}
 	else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) {
 		;
@@ -433,7 +428,7 @@ int calc_manipulator_stats(ScrArea *sa)
 			break;
 			
 		case V3D_MANIP_NORMAL:
-			if(G.obedit) {
+			if(G.obedit || ob->flag & OB_POSEMODE) {
 				float mat[3][3];
 				int type;
 				
@@ -479,34 +474,6 @@ int calc_manipulator_stats(ScrArea *sa)
 				}
 				break;
 			}
-			/* pose mode is a bit weird, so keep it separated */
-			else if (ob->flag & OB_POSEMODE)
-			{
-				strcpy(t->spacename, "normal");
-				if(normal[0]!=0.0 || normal[1]!=0.0 || normal[2]!=0.0) {
-					float imat[3][3], mat[3][3];
-					
-					/* we need the transpose of the inverse for a normal... */
-					Mat3CpyMat4(imat, ob->obmat);
-					
-					Mat3Inv(mat, imat);
-					Mat3Transp(mat);
-					Mat3MulVecfl(mat, normal);
-					Mat3MulVecfl(mat, plane);
-
-					Normalize(normal);
-					if(0.0==Normalize(plane)) VECCOPY(plane, mat[1]);
-					
-					VECCOPY(mat[2], normal);
-					Crossf(mat[0], normal, plane);
-					Crossf(mat[1], mat[2], mat[0]);
-					
-					Mat4CpyMat3(v3d->twmat, mat);
-					Mat4Ortho(v3d->twmat);
-
-					break;
-				}
-			}
 			/* no break we define 'normal' as 'local' in Object mode */
 		case V3D_MANIP_LOCAL:
 			strcpy(t->spacename, "local");
diff --git a/source/blender/src/transform_orientations.c b/source/blender/src/transform_orientations.c
index 6696fcf95d660b8bd4c5399cf349ad5caf64a088..9c7a2f67b89561b9c08028959cdf95ae676f1122 100644
--- a/source/blender/src/transform_orientations.c
+++ b/source/blender/src/transform_orientations.c
@@ -27,6 +27,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_armature_types.h"
+#include "DNA_action_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_listBase.h"
 #include "DNA_object_types.h"
@@ -68,11 +69,17 @@ void BIF_clearTransformOrientation(void)
 }
  
 void BIF_manageTransformOrientation(int confirm, int set) {
+	Object *ob = OBACT;
 	int index = -1; 
 	
 	if (G.obedit) {
 		if (G.obedit->type == OB_MESH)
 			index = manageMeshSpace(confirm, set);
+		else if (G.obedit->type == OB_ARMATURE)
+			index = manageBoneSpace(confirm, set);
+	}
+	else if (ob && (ob->flag & OB_POSEMODE)) {
+			index = manageBoneSpace(confirm, set);
 	}
 	else {
 		index = manageObjectSpace(confirm, set);
@@ -122,6 +129,31 @@ int confirmSpace(int set, char text[])
 	}
 }
 
+int manageBoneSpace(int confirm, int set) {
+	float mat[3][3];
+	float normal[3], plane[3];
+	char name[36] = "";
+	int index;
+
+	getTransformOrientation(normal, plane, 0);
+	
+	if (confirm == 0 && confirmSpace(set, "Bone") == 0) {
+		return -1;
+	}
+
+	if (createSpaceNormalTangent(mat, normal, plane) == 0) {
+		error("Cannot use zero-length bone");
+		return -1;
+	}
+
+	strcpy(name, "Bone");
+
+	/* Input name */
+	sbutton(name, 1, 35, "name: ");
+
+	index = addMatrixSpace(mat, name);
+	return index;
+}
 
 int manageMeshSpace(int confirm, int set) {
 	float mat[3][3];
@@ -363,6 +395,29 @@ void applyTransformOrientation() {
   	}
 }
 
+static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) 
+{
+	Bone *bone;
+	int do_next;
+	int total = 0;
+	
+	for(bone= lb->first; bone; bone= bone->next) {
+		bone->flag &= ~BONE_TRANSFORM;
+		do_next = do_it;
+		if(do_it) {
+			if(bone->layer & arm->layer) {
+				if (bone->flag & BONE_SELECTED) {
+					bone->flag |= BONE_TRANSFORM;
+					total++;
+					do_next= 0;	// no transform on children if one parent bone is selected
+				}
+			}
+		}
+		total += count_bone_select(arm, &bone->childbase, do_next);
+	}
+	
+	return total;
+}
 
 int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
 {
@@ -375,6 +430,14 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
 
 	if(G.obedit)
 	{
+		float imat[3][3], mat[3][3];
+		
+		/* we need the transpose of the inverse for a normal... */
+		Mat3CpyMat4(imat, ob->obmat);
+		
+		Mat3Inv(mat, imat);
+		Mat3Transp(mat);
+
 		ob= G.obedit;
 
 		if(G.obedit->type==OB_MESH)
@@ -639,12 +702,48 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
 			}
 
 		}
-		
-		Mat4Mul3Vecfl(G.obedit->obmat, plane);
-		Mat4Mul3Vecfl(G.obedit->obmat, normal);
+
+		/* Vectors from edges don't need the special transpose inverse multiplication */
+		if (result == ORIENTATION_EDGE)
+		{
+			Mat4Mul3Vecfl(ob->obmat, normal);
+			Mat4Mul3Vecfl(ob->obmat, plane);
+		}
+		else
+		{
+			Mat3MulVecfl(mat, normal);
+			Mat3MulVecfl(mat, plane);
+		}
 	}
 	else if(ob && (ob->flag & OB_POSEMODE))
 	{
+		bArmature *arm= ob->data;
+		bPoseChannel *pchan;
+		int totsel;
+		
+		totsel = count_bone_select(arm, &arm->bonebase, 1);
+		if(totsel) {
+			float imat[3][3], mat[3][3];
+
+			/* use channels to get stats */
+			for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+				if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
+					VecAddf(normal, normal, pchan->pose_mat[2]);
+					VecAddf(plane, plane, pchan->pose_mat[1]);
+				}
+			}
+			VecMulf(plane, -1.0);
+			
+			/* we need the transpose of the inverse for a normal... */
+			Mat3CpyMat4(imat, ob->obmat);
+			
+			Mat3Inv(mat, imat);
+			Mat3Transp(mat);
+			Mat3MulVecfl(mat, normal);
+			Mat3MulVecfl(mat, plane);
+			
+			result = ORIENTATION_EDGE;
+		}
 	}
 	else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE))
 	{
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index 2904ca60a124bb6b63dd40c542009c523bacf519..1e45f2bf3e049c334a84f102e517a76945a7fe86 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -1448,6 +1448,8 @@ void obmat_to_viewmat(Object *ob, short smooth)
 	float bmat[4][4];
 	float tmat[3][3];
 
+	G.vd->view= 0; /* dont show the grid */
+
 	Mat4CpyMat4(bmat, ob->obmat);
 	Mat4Ortho(bmat);
 	Mat4Invert(G.vd->viewmat, bmat);