Animato - Basic version patching support
[blender.git] / source / blender / blenloader / intern / readfile.c
index 4fffaf02b09102a536094221af956b232070dd0d..23f22523e194b2fc7e9d18755b1cf629d67a9647 100644 (file)
@@ -34,6 +34,7 @@
 #include "BLI_winstuff.h"
 #endif
 
+#include <limits.h>
 #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
 #include <stdlib.h> // for getenv atoi
 #include <fcntl.h> // for open
     #include <io.h> // for open close read
 #endif
 
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_ID.h"
 #include "DNA_actuator_types.h"
 #include "DNA_brush_types.h"
 #include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
 #include "DNA_color_types.h"
 #include "DNA_controller_types.h"
 #include "DNA_constraint_types.h"
@@ -62,6 +65,7 @@
 #include "DNA_fileglobal_types.h"
 #include "DNA_genfile.h"
 #include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_ipo_types.h"
 #include "DNA_image_types.h"
 #include "DNA_key_types.h"
 #include "BLI_arithb.h"
 #include "BLI_storage_types.h" // for relname flags
 
+#include "BKE_animsys.h"
 #include "BKE_action.h"
 #include "BKE_armature.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_cloth.h"
 #include "BKE_colortools.h"
 #include "BKE_constraint.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
 #include "BKE_deform.h"
 #include "BKE_depsgraph.h"
-#include "BKE_effect.h" // for give_parteff
+#include "BKE_effect.h" /* give_parteff */
+#include "BKE_fcurve.h"
 #include "BKE_global.h" // for G
 #include "BKE_group.h"
 #include "BKE_image.h"
+#include "BKE_ipo.h" 
 #include "BKE_key.h" //void set_four_ipo
 #include "BKE_lattice.h"
 #include "BKE_library.h" // for wich_libbase
 #include "BKE_main.h" // for Main
 #include "BKE_mesh.h" // for ME_ defines (patching)
 #include "BKE_modifier.h"
+#include "BKE_multires.h"
 #include "BKE_node.h" // for tree type defines
 #include "BKE_object.h"
 #include "BKE_particle.h"
-#include "BKE_property.h" // for get_property
+#include "BKE_pointcache.h"
+#include "BKE_property.h" // for get_ob_property
+#include "BKE_report.h"
 #include "BKE_sca.h" // for init_actuator
 #include "BKE_scene.h"
 #include "BKE_softbody.h"      // sbNew()
+#include "BKE_bullet.h"                // bsbNew()
+#include "BKE_sculpt.h"
+#include "BKE_sequence.h"
 #include "BKE_texture.h" // for open_plugin_tex
 #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
 #include "BKE_idprop.h"
 
 #include "readfile.h"
 
-//XXX #include "wm_event_types.h"
-
 #include <errno.h>
 
 /*
@@ -704,7 +717,7 @@ BHead *blo_firstbhead(FileData *fd)
 
 BHead *blo_prevbhead(FileData *fd, BHead *thisblock)
 {
-       BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead));
+       BHeadN *bheadn= (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) );
        BHeadN *prev= bheadn->prev;
 
        return prev?&prev->bhead:NULL;
@@ -712,13 +725,13 @@ BHead *blo_prevbhead(FileData *fd, BHead *thisblock)
 
 BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
 {
-       BHeadN *new_bhead = 0;
-       BHead *bhead = 0;
+       BHeadN *new_bhead = NULL;
+       BHead *bhead = NULL;
 
        if (thisblock) {
                // bhead is actually a sub part of BHeadN
                // We calculate the BHeadN pointer from the BHead pointer below
-               new_bhead = (BHeadN *) (((char *) thisblock) - (int) (&((BHeadN*)0)->bhead));
+               new_bhead = (BHeadN *) (((char *) thisblock) - GET_INT_FROM_POINTER( &((BHeadN*)0)->bhead) );
 
                // get the next BHeadN. If it doesn't exist we read in the next one
                new_bhead = new_bhead->next;
@@ -801,7 +814,7 @@ static int read_file_dna(FileData *fd)
        return 0;
 }
 
-static int fd_read_from_file(FileData *filedata, void *buffer, int size)
+static int fd_read_from_file(FileData *filedata, void *buffer, unsigned int size)
 {
        int readsize = read(filedata->filedes, buffer, size);
 
@@ -814,7 +827,7 @@ static int fd_read_from_file(FileData *filedata, void *buffer, int size)
        return (readsize);
 }
 
-static int fd_read_gzip_from_file(FileData *filedata, void *buffer, int size)
+static int fd_read_gzip_from_file(FileData *filedata, void *buffer, unsigned int size)
 {
        int readsize = gzread(filedata->gzfiledes, buffer, size);
 
@@ -827,7 +840,7 @@ static int fd_read_gzip_from_file(FileData *filedata, void *buffer, int size)
        return (readsize);
 }
 
-static int fd_read_from_memory(FileData *filedata, void *buffer, int size)
+static int fd_read_from_memory(FileData *filedata, void *buffer, unsigned int size)
 {
                // don't read more bytes then there are available in the buffer
        int readsize = MIN2(size, filedata->buffersize - filedata->seek);
@@ -838,11 +851,12 @@ static int fd_read_from_memory(FileData *filedata, void *buffer, int size)
        return (readsize);
 }
 
-static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
+static int fd_read_from_memfile(FileData *filedata, void *buffer, unsigned int size)
 {
        static unsigned int seek= 1<<30;        /* the current position */
        static unsigned int offset= 0;          /* size of previous chunks */
        static MemFileChunk *chunk=NULL;
+       unsigned int chunkoffset, readsize, totread;
        
        if(size==0) return 0;
        
@@ -860,29 +874,39 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
        }
        
        if(chunk) {
-               /* first check if it's on the end if current chunk */
-               if( seek-offset == chunk->size) {
-                       offset+= chunk->size;
-                       chunk= chunk->next;
-               }
-               
-               /* debug, should never happen */
-               if(chunk==NULL) {
-                       printf("illegal read, chunk zero\n");
-                       return 0;
-               }
-               else if( (seek-offset)+size > chunk->size) {
-                       size= chunk->size - (seek-offset);
-                       printf("chunk too large, clipped to %d\n", size);
-               }
-               
-               memcpy(buffer, chunk->buf + (seek-offset), size);
-               filedata->seek += size;
-               seek+= size;
-               
-               return (size);
+               totread= 0;
+
+               do {
+                       /* first check if it's on the end if current chunk */
+                       if(seek-offset == chunk->size) {
+                               offset+= chunk->size;
+                               chunk= chunk->next;
+                       }
+
+                       /* debug, should never happen */
+                       if(chunk==NULL) {
+                               printf("illegal read, chunk zero\n");
+                               return 0;
+                       }
+
+                       chunkoffset= seek-offset;
+                       readsize= size-totread;
+
+                       /* data can be spread over multiple chunks, so clamp size
+                        * to within this chunk, and then it will read further in
+                        * the next chunk */
+                       if(chunkoffset+readsize > chunk->size)
+                               readsize= chunk->size-chunkoffset;
+
+                       memcpy((char*)buffer+totread, chunk->buf+chunkoffset, readsize);
+                       totread += readsize;
+                       filedata->seek += readsize;
+                       seek += readsize;
+               } while(totread < size);
                
+               return totread;
        }
+
        return 0;
 }
 
@@ -906,19 +930,19 @@ static FileData *filedata_new(void)
        return fd;
 }
 
-static FileData *blo_decode_and_check(FileData *fd, BlendReadError *error_r)
+static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
 {
        decode_blender_header(fd);
 
        if (fd->flags & FD_FLAGS_FILE_OK) {
                if (!read_file_dna(fd)) {
-                       *error_r = BRE_INCOMPLETE;
+                       BKE_report(reports, RPT_ERROR, "File incomplete");
                        blo_freefiledata(fd);
                        fd= NULL;
                }
        } 
        else {
-               *error_r = BRE_NOT_A_BLEND;
+               BKE_report(reports, RPT_ERROR, "File is not a Blender file");
                blo_freefiledata(fd);
                fd= NULL;
        }
@@ -928,29 +952,31 @@ static FileData *blo_decode_and_check(FileData *fd, BlendReadError *error_r)
 
 /* cannot be called with relative paths anymore! */
 /* on each new library added, it now checks for the current FileData and expands relativeness */
-FileData *blo_openblenderfile(char *name, BlendReadError *error_r)
+FileData *blo_openblenderfile(char *name, ReportList *reports)
 {
        gzFile gzfile;
        
        gzfile= gzopen(name, "rb");
 
        if (NULL == gzfile) {
-               *error_r = BRE_UNABLE_TO_OPEN;
+               BKE_report(reports, RPT_ERROR, "Unable to open");
                return NULL;
        } else {
                FileData *fd = filedata_new();
                fd->gzfiledes = gzfile;
-               BLI_strncpy(fd->filename, name, sizeof(fd->filename));  // now only in use by library append
                fd->read = fd_read_gzip_from_file;
 
-               return blo_decode_and_check(fd, error_r);
+               /* needed for library_append and read_libraries */
+               BLI_strncpy(fd->filename, name, sizeof(fd->filename));
+
+               return blo_decode_and_check(fd, reports);
        }
 }
 
-FileData *blo_openblendermemory(void *mem, int memsize, BlendReadError *error_r)
+FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports)
 {
        if (!mem || memsize<SIZEOFBLENDERHEADER) {
-               *error_r = mem?BRE_UNABLE_TO_READ:BRE_UNABLE_TO_OPEN;
+               BKE_report(reports, RPT_ERROR, (mem)? "Unable to read": "Unable to open");
                return NULL;
        } else {
                FileData *fd= filedata_new();
@@ -959,14 +985,14 @@ FileData *blo_openblendermemory(void *mem, int memsize, BlendReadError *error_r)
                fd->read= fd_read_from_memory;
                fd->flags|= FD_FLAGS_NOT_MY_BUFFER;
 
-               return blo_decode_and_check(fd, error_r);
+               return blo_decode_and_check(fd, reports);
        }
 }
 
-FileData *blo_openblendermemfile(MemFile *memfile, BlendReadError *error_r)
+FileData *blo_openblendermemfile(MemFile *memfile, ReportList *reports)
 {
        if (!memfile) {
-               *error_r = BRE_UNABLE_TO_OPEN;
+               BKE_report(reports, RPT_ERROR, "Unable to open");
                return NULL;
        } else {
                FileData *fd= filedata_new();
@@ -975,7 +1001,7 @@ FileData *blo_openblendermemfile(MemFile *memfile, BlendReadError *error_r)
                fd->read= fd_read_from_memfile;
                fd->flags|= FD_FLAGS_NOT_MY_BUFFER;
 
-               return blo_decode_and_check(fd, error_r);
+               return blo_decode_and_check(fd, reports);
        }
 }
 
@@ -1016,7 +1042,9 @@ void blo_freefiledata(FileData *fd)
                        oldnewmap_free(fd->imamap);
                if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
                        oldnewmap_free(fd->libmap);
-
+               if (fd->bheadmap)
+                       MEM_freeN(fd->bheadmap);
+               
                MEM_freeN(fd);
        }
 }
@@ -1094,11 +1122,23 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi
        }
 }
 
-/* assumed; G.main still exists */
-void blo_make_image_pointer_map(FileData *fd)
+/* lib linked proxy objects point to our local data, we need
+ * to clear that pointer before reading the undo memfile since
+ * the object might be removed, it is set again in reading
+ * if the local object still exists */
+void blo_clear_proxy_pointers_from_lib(FileData *fd, Main *oldmain)
+{
+       Object *ob= oldmain->object.first;
+       
+       for(;ob; ob= ob->id.next)
+               if(ob->id.lib)
+                       ob->proxy_from= NULL;
+}
+
+void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
 {
-       Image *ima= G.main->image.first;
-       Scene *sce= G.main->scene.first;
+       Image *ima= oldmain->image.first;
+       Scene *sce= oldmain->scene.first;
        
        fd->imamap= oldnewmap_new();
        
@@ -1106,6 +1146,8 @@ void blo_make_image_pointer_map(FileData *fd)
                Link *ibuf= ima->ibufs.first;
                for(; ibuf; ibuf= ibuf->next) 
                        oldnewmap_insert(fd->imamap, ibuf, ibuf, 0);
+               if(ima->gputexture)
+                       oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1116,13 +1158,13 @@ void blo_make_image_pointer_map(FileData *fd)
        }
 }
 
-/* set G.main image ibufs to zero if it has been restored */
-/* this works because freeing G.main only happens after this call */
-void blo_end_image_pointer_map(FileData *fd)
+/* set old main image ibufs to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
 {
        OldNew *entry= fd->imamap->entries;
-       Image *ima= G.main->image.first;
-       Scene *sce= G.main->scene.first;
+       Image *ima= oldmain->image.first;
+       Scene *sce= oldmain->scene.first;
        int i;
        
        /* used entries were restored, so we put them to zero */
@@ -1140,8 +1182,11 @@ void blo_end_image_pointer_map(FileData *fd)
                        if(NULL==newimaadr(fd, ibuf)) { /* so was restored */
                                BLI_remlink(&ima->ibufs, ibuf);
                                ima->bindcode= 0;
+                               ima->gputexture= NULL;
                        }
                }
+
+               ima->gputexture= newimaadr(fd, ima->gputexture);
        }
        for(; sce; sce= sce->id.next) {
                if(sce->nodetree) {
@@ -1303,11 +1348,30 @@ static void test_pointer_array(FileData *fd, void **mat)
 
 /* ************ READ ID Properties *************** */
 
-void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd);
-void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd);
+void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
+void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
+
+static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd)
+{
+       IDProperty **array;
+       int i;
+
+       /*since we didn't save the extra buffer, set totallen to len.*/
+       prop->totallen = prop->len;
+       prop->data.pointer = newdataadr(fd, prop->data.pointer);
+
+       if (switch_endian) {
+               test_pointer_array(fd, prop->data.pointer);
+               array= (IDProperty**) prop->data.pointer;
+
+               for(i=0; i<prop->len; i++)
+                       IDP_DirectLinkProperty(array[i], switch_endian, fd);
+       }
+}
 
-void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd)
+static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd)
 {
+       IDProperty **array;
        int i;
 
        /*since we didn't save the extra buffer, set totallen to len.*/
@@ -1315,20 +1379,33 @@ void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd)
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
        if (switch_endian) {
-               for (i=0; i<prop->len; i++) {
-                       SWITCH_INT(((int*)prop->data.pointer)[i]);
+               if(prop->subtype == IDP_GROUP) {
+                       test_pointer_array(fd, prop->data.pointer);
+                       array= prop->data.pointer;
+
+                       for(i=0; i<prop->len; i++)
+                               IDP_DirectLinkProperty(array[i], switch_endian, fd);
+               }
+               else if(prop->subtype == IDP_DOUBLE) {
+                       for (i=0; i<prop->len; i++) {
+                               SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
+                       }
+               } else {
+                       for (i=0; i<prop->len; i++) {
+                               SWITCH_INT(((int*)prop->data.pointer)[i]);
+                       }
                }
        }
 }
 
-void IDP_DirectLinkString(IDProperty *prop, int switch_endian, void *fd)
+static void IDP_DirectLinkString(IDProperty *prop, int switch_endian, FileData *fd)
 {
        /*since we didn't save the extra string buffer, set totallen to len.*/
        prop->totallen = prop->len;
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 }
 
-void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd)
+static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, FileData *fd)
 {
        ListBase *lb = &prop->data.group;
        IDProperty *loop;
@@ -1341,7 +1418,7 @@ void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd)
        }
 }
 
-void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
+void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
 {
        switch (prop->type) {
                case IDP_GROUP:
@@ -1352,13 +1429,50 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
                        break;
                case IDP_ARRAY:
                        IDP_DirectLinkArray(prop, switch_endian, fd);
+                       break;
+               case IDP_IDPARRAY:
+                       IDP_DirectLinkIDPArray(prop, switch_endian, fd);
+                       break;
+               case IDP_DOUBLE:
+                       /*erg, stupid doubles.  since I'm storing them
+                        in the same field as int val; val2 in the
+                        IDPropertyData struct, they have to deal with
+                        endianness specifically
+                        
+                        in theory, val and val2 would've already been swapped
+                        if switch_endian is true, so we have to first unswap
+                        them then reswap them as a single 64-bit entity.
+                        */
+                       
+                       if (switch_endian) {
+                               SWITCH_INT(prop->data.val);
+                               SWITCH_INT(prop->data.val2);
+                               SWITCH_LONGINT(prop->data.val);
+                       }
+                       
                        break;
        }
 }
 
 /*stub function*/
-void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd)
+void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
+{
+}
+
+/* ************ READ CurveMapping *************** */
+
+/* cuma itself has been read! */
+static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
 {
+       int a;
+       
+       /* flag seems to be able to hang? Maybe old files... not bad to clear anyway */
+       cumap->flag &= ~CUMA_PREMULLED;
+       
+       for(a=0; a<CM_TOT; a++) {
+               cumap->cm[a].curve= newdataadr(fd, cumap->cm[a].curve);
+               cumap->cm[a].table= NULL;
+       }
 }
 
 /* ************ READ Brush *************** */
@@ -1379,6 +1493,8 @@ static void lib_link_brush(FileData *fd, Main *main)
                                if(mtex)
                                        mtex->tex= newlibadr_us(fd, brush->id.lib, mtex->tex);
                        }
+
+                       brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image);
                }
        }
 }
@@ -1390,22 +1506,17 @@ static void direct_link_brush(FileData *fd, Brush *brush)
 
        for(a=0; a<MAX_MTEX; a++)
                brush->mtex[a]= newdataadr(fd, brush->mtex[a]);
-}
 
-/* ************ READ CurveMapping *************** */
+       /* fallof curve */
+       brush->curve= newdataadr(fd, brush->curve);
+       if(brush->curve)
+               direct_link_curvemapping(fd, brush->curve);
+}
 
-/* cuma itself has been read! */
-static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
+static void direct_link_script(FileData *fd, Script *script)
 {
-       int a;
-       
-       /* flag seems to be able to hang? Maybe old files... not bad to clear anyway */
-       cumap->flag &= ~CUMA_PREMULLED;
-       
-       for(a=0; a<CM_TOT; a++) {
-               cumap->cm[a].curve= newdataadr(fd, cumap->cm[a].curve);
-               cumap->cm[a].table= NULL;
-       }
+       script->id.us = 1;
+       SCRIPT_SET_NULL(script)
 }
 
 /* ************ READ NODE TREE *************** */
@@ -1434,11 +1545,19 @@ static void lib_link_nodetree(FileData *fd, Main *main)
 }
 
 /* verify types for nodes and groups, all data has to be read */
-static void lib_verify_nodetree(Main *main)
+/* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
+ * typedefs*/
+static void lib_verify_nodetree(Main *main, int open)
 {
        Scene *sce;
        Material *ma;
+       Tex *tx;
        bNodeTree *ntree;
+
+       /* this crashes blender on undo/redo
+       if(open==1) {
+               reinit_nodesystem();
+       }*/
        
        /* now create the own typeinfo structs an verify nodes */
        /* here we still assume no groups in groups */
@@ -1457,6 +1576,11 @@ static void lib_verify_nodetree(Main *main)
                if(sce->nodetree)
                        ntreeVerifyTypes(sce->nodetree);
        }
+       /* and texture trees */
+       for(tx= main->tex.first; tx; tx= tx->id.next) {
+               if(tx->nodetree)
+                       ntreeVerifyTypes(tx->nodetree);
+       }
 }
 
 
@@ -1475,6 +1599,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        
        link_list(fd, &ntree->nodes);
        for(node= ntree->nodes.first; node; node= node->next) {
+               if(node->type == NODE_DYNAMIC) {
+                       node->custom1= 0;
+                       node->custom1= BSET(node->custom1, NODE_DYNAMIC_LOADED);
+                       node->typeinfo= NULL;
+               }
+
                node->storage= newdataadr(fd, node->storage);
                if(node->storage) {
                        
@@ -1487,6 +1617,9 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                                else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
                                        ((ImageUser *)node->storage)->ok= 1;
                        }
+                       else if( ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) {
+                               direct_link_curvemapping(fd, node->storage);
+                       }
                }
                link_list(fd, &node->inputs);
                link_list(fd, &node->outputs);
@@ -1509,6 +1642,22 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                link->tosock= newdataadr(fd, link->tosock);
        }
        
+       /* set selin and selout */
+       for(node= ntree->nodes.first; node; node= node->next) {
+               for(sock= node->inputs.first; sock; sock= sock->next) {
+                       if(sock->flag & SOCK_SEL) {
+                               ntree->selin= sock;
+                               break;
+                       }
+               }
+               for(sock= node->outputs.first; sock; sock= sock->next) {
+                       if(sock->flag & SOCK_SEL) {
+                               ntree->selout= sock;
+                               break;
+                       }
+               }
+       }
+       
        /* type verification is in lib-link */
 }
 
@@ -1570,8 +1719,45 @@ static void direct_link_scriptlink(FileData *fd, ScriptLink *slink)
        }
 }
 
-/* ************ READ ARMATURE ***************** */
+/* ************ READ ANIMATION STUFF ***************** */
+
+/* Legacy Data Support (for Version Patching) ----------------------------- */
+
+// XXX depreceated - old animation system
+static void lib_link_ipo(FileData *fd, Main *main)
+{
+       Ipo *ipo;
+
+       ipo= main->ipo.first;
+       while(ipo) {
+               if(ipo->id.flag & LIB_NEEDLINK) {
+                       IpoCurve *icu;
+                       for(icu= ipo->curve.first; icu; icu= icu->next) {
+                               if(icu->driver)
+                                       icu->driver->ob= newlibadr(fd, ipo->id.lib, icu->driver->ob);
+                       }
+                       ipo->id.flag -= LIB_NEEDLINK;
+               }
+               ipo= ipo->id.next;
+       }
+}
+
+// XXX depreceated - old animation system
+static void direct_link_ipo(FileData *fd, Ipo *ipo)
+{
+       IpoCurve *icu;
+
+       link_list(fd, &(ipo->curve));
+       icu= ipo->curve.first;
+       while(icu) {
+               icu->bezt= newdataadr(fd, icu->bezt);
+               icu->bp= newdataadr(fd, icu->bp);
+               icu->driver= newdataadr(fd, icu->driver);
+               icu= icu->next;
+       }
+}
 
+// XXX depreceated - old animation system
 static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
 {
        bActionStrip *strip;
@@ -1586,6 +1772,18 @@ static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
        }
 }
 
+// XXX depreceated - old animation system
+static void direct_link_nlastrips(FileData *fd, ListBase *strips)
+{
+       bActionStrip *strip;
+       
+       link_list(fd, strips);
+       
+       for(strip= strips->first; strip; strip= strip->next)
+               link_list(fd, &strip->modifiers);
+}
+
+// XXX depreceated - old animation system
 static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase)
 {
        bConstraintChannel *chan;
@@ -1595,6 +1793,178 @@ static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbas
        }
 }
 
+/* Data Linking ----------------------------- */
+
+static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list) 
+{
+       FCurve *fcu;
+       FModifier *fcm;
+       
+       /* relink ID-block references... */
+       for (fcu= list->first; fcu; fcu= fcu->next) {
+               /* driver data */
+               if (fcu->driver) {
+                       ChannelDriver *driver= fcu->driver;
+                       driver->id= newlibadr(fd, id->lib, driver->id); 
+                       driver->id2= newlibadr(fd, id->lib, driver->id2); 
+               }
+               
+               /* modifiers */
+               for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
+                       /* data for specific modifiers */
+                       switch (fcm->type) {
+                               case FMODIFIER_TYPE_PYTHON:
+                               {
+                                       FMod_Python *data= (FMod_Python *)fcm->data;
+                                       data->script = newlibadr(fd, id->lib, data->script);
+                               }
+                                       break;
+                       }
+               }
+       }
+}
+
+/* NOTE: this assumes that link_list has already been called on the list */
+static void direct_link_fcurves(FileData *fd, ListBase *list)
+{
+       FCurve *fcu;
+       FModifier *fcm;
+       
+       /* link F-Curve data to F-Curve again (non ID-libs) */
+       for (fcu= list->first; fcu; fcu= fcu->next) {
+               /* curve data */
+               fcu->bezt= newdataadr(fd, fcu->bezt);
+               fcu->fpt= newdataadr(fd, fcu->fpt);
+               
+               /* rna path */
+               fcu->rna_path= newdataadr(fd, fcu->rna_path);
+               
+               /* group */
+               fcu->grp= newdataadr(fd, fcu->grp);
+               
+               /* driver */
+               fcu->driver= newdataadr(fd, fcu->driver);
+               if (fcu->driver) {
+                       ChannelDriver *driver= fcu->driver;
+                       
+                       driver->rna_path= newdataadr(fd, driver->rna_path);
+                       driver->rna_path2= newdataadr(fd, driver->rna_path2);
+               }
+               
+               /* modifiers */
+               link_list(fd, &fcu->modifiers);
+               for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
+                       /* relink general data */
+                       fcm->data = newdataadr(fd, fcm->data);
+                       
+                       /* do relinking of data for specific types */
+                       switch (fcm->type) {
+                               case FMODIFIER_TYPE_GENERATOR:
+                               {
+                                       FMod_Generator *data= (FMod_Generator *)fcm->data;
+                                       
+                                       data->poly_coefficients= newdataadr(fd, data->poly_coefficients);
+                               }
+                                       break;
+                               case FMODIFIER_TYPE_PYTHON:
+                               {
+                                       FMod_Python *data= (FMod_Python *)fcm->data;
+                                       
+                                       data->prop = newdataadr(fd, data->prop);
+                                       IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                               }
+                                       break;
+                       }
+               }
+       }
+}
+
+
+static void lib_link_action(FileData *fd, Main *main)
+{
+       bAction *act;
+       bActionChannel *chan;
+
+       for (act= main->action.first; act; act= act->id.next) {
+               if (act->id.flag & LIB_NEEDLINK) {
+                       act->id.flag -= LIB_NEEDLINK;
+                       
+// XXX depreceated - old animation system <<<
+                       for (chan=act->chanbase.first; chan; chan=chan->next) {
+                               chan->ipo= newlibadr_us(fd, act->id.lib, chan->ipo);
+                               lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
+                       }
+// >>> XXX depreceated - old animation system
+                       
+                       lib_link_fcurves(fd, &act->id, &act->curves);
+               }
+       }
+}
+
+static void direct_link_action(FileData *fd, bAction *act)
+{
+       bActionChannel *achan; // XXX depreceated - old animation system
+       bActionGroup *agrp;
+
+       link_list(fd, &act->curves);
+       link_list(fd, &act->chanbase); // XXX depreceated - old animation system
+       link_list(fd, &act->groups);
+       link_list(fd, &act->markers);
+
+// XXX depreceated - old animation system <<<
+       for (achan = act->chanbase.first; achan; achan=achan->next) {
+               achan->grp= newdataadr(fd, achan->grp);
+               
+               link_list(fd, &achan->constraintChannels);
+       }
+// >>> XXX depreceated - old animation system
+
+       direct_link_fcurves(fd, &act->curves);
+       
+       for (agrp = act->groups.first; agrp; agrp= agrp->next) {
+               agrp->channels.first= newdataadr(fd, agrp->channels.first);
+               agrp->channels.last= newdataadr(fd, agrp->channels.last);
+       }
+}
+
+/* ------- */
+
+static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
+{
+       if (adt == NULL)
+               return;
+       
+       /* link action data */
+       adt->action= newlibadr_us(fd, id->lib, adt->action);
+       
+       /* link drivers */
+       lib_link_fcurves(fd, id, &adt->drivers);
+       
+       /* overrides don't have lib-link for now, so no need to do anything */
+       
+       /* link NLA-data */
+       // TODO... 
+}
+
+static void direct_link_animdata(FileData *fd, AnimData *adt)
+{
+       /* NOTE: must have called newdataadr already before doing this... */
+       if (adt == NULL)
+               return;
+       
+       /* link drivers */
+       link_list(fd, &adt->drivers);
+       direct_link_fcurves(fd, &adt->drivers);
+       
+       /* link overrides */
+       // TODO...
+       
+       /* link NLA-data */
+       // TODO...
+}      
+
+/* ************ READ ARMATURE ***************** */
+
 static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
 {
        bConstraint *con;
@@ -1606,7 +1976,7 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                        con->type= CONSTRAINT_TYPE_NULL;
                }
                /* own ipo, all constraints have it */
-               con->ipo= newlibadr_us(fd, id->lib, con->ipo);
+               con->ipo= newlibadr_us(fd, id->lib, con->ipo); // XXX depreceated - old animation system
                
                switch (con->type) {
                case CONSTRAINT_TYPE_PYTHON:
@@ -1721,6 +2091,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                data->tar = newlibadr(fd, id->lib, data->tar);
                        }
                        break;
+               case CONSTRAINT_TYPE_DISTLIMIT:
+                       {
+                               bDistLimitConstraint *data;
+                               data= ((bDistLimitConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       }
+                       break;
                case CONSTRAINT_TYPE_NULL:
                        break;
                }
@@ -1734,6 +2111,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
        link_list(fd, lb);
        for (cons=lb->first; cons; cons=cons->next) {
                cons->data = newdataadr(fd, cons->data);
+               
                if (cons->type == CONSTRAINT_TYPE_PYTHON) {
                        bPythonConstraint *data= cons->data;
                        link_list(fd, &data->targets);
@@ -1791,26 +2169,6 @@ static void lib_link_armature(FileData *fd, Main *main)
        }
 }
 
-static void lib_link_action(FileData *fd, Main *main)
-{
-       bAction *act;
-       bActionChannel *chan;
-
-       act= main->action.first;
-       while(act) {
-               if(act->id.flag & LIB_NEEDLINK) {
-                       act->id.flag -= LIB_NEEDLINK;
-
-                       for (chan=act->chanbase.first; chan; chan=chan->next) {
-                               chan->ipo= newlibadr_us(fd, act->id.lib, chan->ipo);
-                               lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
-                       }
-
-               }
-               act= act->id.next;
-       }
-}
-
 static void direct_link_bones(FileData *fd, Bone* bone)
 {
        Bone    *child;
@@ -1824,24 +2182,13 @@ static void direct_link_bones(FileData *fd, Bone* bone)
        }
 }
 
-
-static void direct_link_action(FileData *fd, bAction *act)
-{
-       bActionChannel *achan;
-
-       link_list(fd, &act->chanbase);
-
-       for (achan = act->chanbase.first; achan; achan=achan->next)
-               link_list(fd, &achan->constraintChannels);
-
-}
-
 static void direct_link_armature(FileData *fd, bArmature *arm)
 {
        Bone    *bone;
 
        link_list(fd, &arm->bonebase);
-
+       arm->edbo= NULL;
+       
        bone=arm->bonebase.first;
        while (bone) {
                direct_link_bones(fd, bone);
@@ -1858,13 +2205,14 @@ static void lib_link_camera(FileData *fd, Main *main)
        ca= main->camera.first;
        while(ca) {
                if(ca->id.flag & LIB_NEEDLINK) {
-
-                       ca->ipo= newlibadr_us(fd, ca->id.lib, ca->ipo);
+                       if (ca->adt) lib_link_animdata(fd, &ca->id, ca->adt);
+                       
+                       ca->ipo= newlibadr_us(fd, ca->id.lib, ca->ipo); // XXX depreceated - old animation system
                        
                        ca->dof_ob= newlibadr_us(fd, ca->id.lib, ca->dof_ob);
                        
                        lib_link_scriptlink(fd, &ca->id, &ca->scriptlink);
-
+                       
                        ca->id.flag -= LIB_NEEDLINK;
                }
                ca= ca->id.next;
@@ -1873,6 +2221,9 @@ static void lib_link_camera(FileData *fd, Main *main)
 
 static void direct_link_camera(FileData *fd, Camera *ca)
 {
+       ca->adt= newdataadr(fd, ca->adt);
+       direct_link_animdata(fd, ca->adt);
+       
        direct_link_scriptlink(fd, &ca->scriptlink);
 }
 
@@ -1888,7 +2239,8 @@ static void lib_link_lamp(FileData *fd, Main *main)
        la= main->lamp.first;
        while(la) {
                if(la->id.flag & LIB_NEEDLINK) {
-
+                       if (la->adt) lib_link_animdata(fd, &la->id, la->adt);
+                       
                        for(a=0; a<MAX_MTEX; a++) {
                                mtex= la->mtex[a];
                                if(mtex) {
@@ -1896,11 +2248,11 @@ static void lib_link_lamp(FileData *fd, Main *main)
                                        mtex->object= newlibadr(fd, la->id.lib, mtex->object);
                                }
                        }
-
-                       la->ipo= newlibadr_us(fd, la->id.lib, la->ipo);
-
+                       
+                       la->ipo= newlibadr_us(fd, la->id.lib, la->ipo); // XXX depreceated - old animation system
+                       
                        lib_link_scriptlink(fd, &la->id, &la->scriptlink);
-
+                       
                        la->id.flag -= LIB_NEEDLINK;
                }
                la= la->id.next;
@@ -1910,7 +2262,10 @@ static void lib_link_lamp(FileData *fd, Main *main)
 static void direct_link_lamp(FileData *fd, Lamp *la)
 {
        int a;
-
+       
+       la->adt= newdataadr(fd, la->adt);
+       direct_link_animdata(fd, la->adt);
+       
        direct_link_scriptlink(fd, &la->scriptlink);
 
        for(a=0; a<MAX_MTEX; a++) {
@@ -1934,7 +2289,7 @@ static void lib_link_key(FileData *fd, Main *main)
        while(key) {
                if(key->id.flag & LIB_NEEDLINK) {
 
-                       key->ipo= newlibadr_us(fd, key->id.lib, key->ipo);
+                       key->ipo= newlibadr_us(fd, key->id.lib, key->ipo); // XXX depreceated - old animation system
                        key->from= newlibadr(fd, key->id.lib, key->from);
 
                        key->id.flag -= LIB_NEEDLINK;
@@ -1983,6 +2338,9 @@ static void direct_link_key(FileData *fd, Key *key)
 
        link_list(fd, &(key->block));
 
+       key->adt= newdataadr(fd, key->adt);
+       direct_link_animdata(fd, key->adt);
+       
        key->refkey= newdataadr(fd, key->refkey);
 
        kb= key->block.first;
@@ -2010,7 +2368,7 @@ static void lib_link_mball(FileData *fd, Main *main)
 
                        for(a=0; a<mb->totcol; a++) mb->mat[a]= newlibadr_us(fd, mb->id.lib, mb->mat[a]);
 
-                       mb->ipo= newlibadr_us(fd, mb->id.lib, mb->ipo);
+                       mb->ipo= newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX depreceated - old animation system
 
                        mb->id.flag -= LIB_NEEDLINK;
                }
@@ -2025,9 +2383,9 @@ static void direct_link_mball(FileData *fd, MetaBall *mb)
 
        link_list(fd, &(mb->elems));
 
-       mb->disp.first= mb->disp.last= 0;
-
-       mb->bb= 0;
+       mb->disp.first= mb->disp.last= NULL;
+       mb->editelems= NULL;
+       mb->bb= NULL;
 }
 
 /* ************ READ WORLD ***************** */
@@ -2041,9 +2399,10 @@ static void lib_link_world(FileData *fd, Main *main)
        wrld= main->world.first;
        while(wrld) {
                if(wrld->id.flag & LIB_NEEDLINK) {
-
-                       wrld->ipo= newlibadr_us(fd, wrld->id.lib, wrld->ipo);
-
+                       if (wrld->adt) lib_link_animdata(fd, &wrld->id, wrld->adt);
+                       
+                       wrld->ipo= newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX depreceated - old animation system
+                       
                        for(a=0; a<MAX_MTEX; a++) {
                                mtex= wrld->mtex[a];
                                if(mtex) {
@@ -2051,9 +2410,9 @@ static void lib_link_world(FileData *fd, Main *main)
                                        mtex->object= newlibadr(fd, wrld->id.lib, mtex->object);
                                }
                        }
-
+                       
                        lib_link_scriptlink(fd, &wrld->id, &wrld->scriptlink);
-
+                       
                        wrld->id.flag -= LIB_NEEDLINK;
                }
                wrld= wrld->id.next;
@@ -2064,6 +2423,9 @@ static void direct_link_world(FileData *fd, World *wrld)
 {
        int a;
 
+       wrld->adt= newdataadr(fd, wrld->adt);
+       direct_link_animdata(fd, wrld->adt);
+       
        direct_link_scriptlink(fd, &wrld->scriptlink);
 
        for(a=0; a<MAX_MTEX; a++) {
@@ -2073,40 +2435,6 @@ static void direct_link_world(FileData *fd, World *wrld)
 }
 
 
-/* ************ READ IPO ***************** */
-
-static void lib_link_ipo(FileData *fd, Main *main)
-{
-       Ipo *ipo;
-
-       ipo= main->ipo.first;
-       while(ipo) {
-               if(ipo->id.flag & LIB_NEEDLINK) {
-                       IpoCurve *icu;
-                       for(icu= ipo->curve.first; icu; icu= icu->next) {
-                               if(icu->driver)
-                                       icu->driver->ob= newlibadr(fd, ipo->id.lib, icu->driver->ob);
-                       }
-                       ipo->id.flag -= LIB_NEEDLINK;
-               }
-               ipo= ipo->id.next;
-       }
-}
-
-static void direct_link_ipo(FileData *fd, Ipo *ipo)
-{
-       IpoCurve *icu;
-
-       link_list(fd, &(ipo->curve));
-       icu= ipo->curve.first;
-       while(icu) {
-               icu->bezt= newdataadr(fd, icu->bezt);
-               icu->bp= newdataadr(fd, icu->bp);
-               icu->driver= newdataadr(fd, icu->driver);
-               icu= icu->next;
-       }
-}
-
 /* ************ READ VFONT ***************** */
 
 static void lib_link_vfont(FileData *fd, Main *main)
@@ -2162,6 +2490,7 @@ static void direct_link_text(FileData *fd, Text *text)
 */
 
        link_list(fd, &text->lines);
+       link_list(fd, &text->markers);
 
        text->curl= newdataadr(fd, text->curl);
        text->sell= newdataadr(fd, text->sell);
@@ -2228,8 +2557,10 @@ static void direct_link_image(FileData *fd, Image *ima)
                ima->ibufs.first= ima->ibufs.last= NULL;
        
        /* if not restored, we keep the binded opengl index */
-       if(ima->ibufs.first==NULL)
+       if(ima->ibufs.first==NULL) {
                ima->bindcode= 0;
+               ima->gputexture= NULL;
+       }
        
        ima->anim= NULL;
        ima->rr= NULL;
@@ -2262,7 +2593,7 @@ static void lib_link_curve(FileData *fd, Main *main)
                        cu->vfonti= newlibadr_us(fd, cu->id.lib, cu->vfonti);
                        cu->vfontbi= newlibadr_us(fd, cu->id.lib, cu->vfontbi);
 
-                       cu->ipo= newlibadr_us(fd, cu->id.lib, cu->ipo);
+                       cu->ipo= newlibadr_us(fd, cu->id.lib, cu->ipo); // XXX depreceated - old animation system
                        cu->key= newlibadr_us(fd, cu->id.lib, cu->key);
 
                        cu->id.flag -= LIB_NEEDLINK;
@@ -2294,7 +2625,10 @@ static void direct_link_curve(FileData *fd, Curve *cu)
 {
        Nurb *nu;
        TextBox *tb;
-
+       
+       cu->adt= newdataadr(fd, cu->adt);
+       direct_link_animdata(fd, cu->adt);
+       
        cu->mat= newdataadr(fd, cu->mat);
        test_pointer_array(fd, (void **)&cu->mat);
        cu->str= newdataadr(fd, cu->str);
@@ -2319,10 +2653,13 @@ static void direct_link_curve(FileData *fd, Curve *cu)
                if (cu->wordspace == 0.0) cu->wordspace = 1.0;
        }
 
-       cu->bev.first=cu->bev.last= 0;
-       cu->disp.first=cu->disp.last= 0;
-       cu->path= 0;
-
+       cu->bev.first=cu->bev.last= NULL;
+       cu->disp.first=cu->disp.last= NULL;
+       cu->editnurb= NULL;
+       cu->lastselbp= NULL;
+       cu->path= NULL;
+       cu->editstr= NULL;
+       
        nu= cu->nurb.first;
        while(nu) {
                nu->bezt= newdataadr(fd, nu->bezt);
@@ -2354,6 +2691,9 @@ static void lib_link_texture(FileData *fd, Main *main)
                        tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
                        if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
 
+                       if(tex->nodetree)
+                               lib_link_ntree(fd, &tex->id, tex->nodetree);
+                       
                        tex->id.flag -= LIB_NEEDLINK;
                }
                tex= tex->id.next;
@@ -2362,6 +2702,9 @@ static void lib_link_texture(FileData *fd, Main *main)
 
 static void direct_link_texture(FileData *fd, Tex *tex)
 {
+       tex->adt= newdataadr(fd, tex->adt);
+       direct_link_animdata(fd, tex->adt);
+       
        tex->plugin= newdataadr(fd, tex->plugin);
        if(tex->plugin) {
                tex->plugin->handle= 0;
@@ -2379,6 +2722,11 @@ static void direct_link_texture(FileData *fd, Tex *tex)
                memset(tex->env->cube, 0, 6*sizeof(void *));
                tex->env->ok= 0;
        }
+       
+       tex->nodetree= newdataadr(fd, tex->nodetree);
+       if(tex->nodetree)
+               direct_link_nodetree(fd, tex->nodetree);
+       
        tex->preview = direct_link_preview_image(fd, tex->preview);
 
        tex->iuser.ok= 1;
@@ -2426,6 +2774,9 @@ static void direct_link_material(FileData *fd, Material *ma)
 {
        int a;
 
+       ma->adt= newdataadr(fd, ma->adt);
+       direct_link_animdata(fd, ma->adt);
+       
        for(a=0; a<MAX_MTEX; a++) {
                ma->mtex[a]= newdataadr(fd, ma->mtex[a]);
        }
@@ -2440,10 +2791,17 @@ static void direct_link_material(FileData *fd, Material *ma)
                direct_link_nodetree(fd, ma->nodetree);
 
        ma->preview = direct_link_preview_image(fd, ma->preview);
+       ma->gpumaterial.first = ma->gpumaterial.last = NULL;
 }
 
 /* ************ READ PARTICLE SETTINGS ***************** */
 
+static void direct_link_pointcache(FileData *fd, PointCache *cache)
+{
+       cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE);
+       cache->simframe= 0;
+}
+
 static void lib_link_particlesettings(FileData *fd, Main *main)
 {
        ParticleSettings *part;
@@ -2451,7 +2809,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
        part= main->particle.first;
        while(part) {
                if(part->id.flag & LIB_NEEDLINK) {
-                       part->ipo= newlibadr_us(fd, part->id.lib, part->ipo);
+                       part->ipo= newlibadr_us(fd, part->id.lib, part->ipo); // XXX depreceated - old animation system
                        part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
                        part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
                        part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
@@ -2465,21 +2823,36 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 {
        part->pd= newdataadr(fd, part->pd);
+       part->pd2= newdataadr(fd, part->pd2);
 }
 
-static void lib_link_particlesystems(FileData *fd, ID *id, ListBase *particles)
+static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
 {
-       ParticleSystem *psys;
+       ParticleSystem *psys, *psysnext;
        int a;
 
-       for(psys=particles->first; psys; psys=psys->next){
+       for(psys=particles->first; psys; psys=psysnext){
                ParticleData *pa;
+               
+               psysnext= psys->next;
+               
                psys->part = newlibadr_us(fd, id->lib, psys->part);
-               psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
-               psys->keyed_ob = newlibadr(fd, id->lib, psys->keyed_ob);
+               if(psys->part) {
+                       psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
+                       psys->keyed_ob = newlibadr(fd, id->lib, psys->keyed_ob);
+
+                       for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){
+                               pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob);
+                       }
+               }
+               else {
+                       /* particle modifier must be removed before particle system */
+                       ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys);
+                       BLI_remlink(&ob->modifiers, psmd);
+                       modifier_free((ModifierData *)psmd);
 
-               for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){
-                       pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob);
+                       BLI_remlink(particles, psys);
+                       MEM_freeN(psys);
                }
        }
 }
@@ -2495,6 +2868,15 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                        for(a=0; a<psys->totpart; a++, pa++)
                                pa->hair=newdataadr(fd,pa->hair);
                }
+               if(psys->particles && psys->particles->keys){
+                       ParticleData *pa = psys->particles;
+                       for(a=0; a<psys->totpart; a++, pa++) {
+                               pa->keys= NULL;
+                               pa->totkey= 0;
+                       }
+
+                       psys->flag &= ~PSYS_KEYED;
+               }
                psys->child=newdataadr(fd,psys->child);
                psys->effectors.first=psys->effectors.last=0;
 
@@ -2505,12 +2887,22 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                        sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
                        sb->bspring= NULL;
                        sb->scratch= NULL;
+
+                       sb->pointcache= newdataadr(fd, sb->pointcache);
+                       if(sb->pointcache)
+                               direct_link_pointcache(fd, sb->pointcache);
                }
 
                psys->edit = 0;
                psys->pathcache = 0;
                psys->childcache = 0;
+               psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
+               psys->childcachebufs.first = psys->childcachebufs.last = 0;
                psys->reactevents.first = psys->reactevents.last = 0;
+
+               psys->pointcache= newdataadr(fd, psys->pointcache);
+               if(psys->pointcache)
+                       direct_link_pointcache(fd, psys->pointcache);
        }
        return;
 }
@@ -2591,6 +2983,19 @@ static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
        }
 }
 
+static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps)
+{
+       if(mdisps) {
+               int i;
+
+               for(i = 0; i < count; ++i) {
+                       mdisps[i].disps = newdataadr(fd, mdisps[i].disps);
+                       if(!mdisps[i].disps)
+                               mdisps[i].totdisp = 0;
+               }
+       }       
+}
+
 static void direct_link_customdata(FileData *fd, CustomData *data, int count)
 {
        int i = 0;
@@ -2602,6 +3007,8 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
 
                if (CustomData_verify_versions(data, i)) {
                        layer->data = newdataadr(fd, layer->data);
+                       if(layer->type == CD_MDISPS)
+                               direct_link_mdisps(fd, count, layer->data);
                        i++;
                }
        }
@@ -2640,7 +3047,8 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
 
        mesh->bb= NULL;
        mesh->mselect = NULL;
-
+       mesh->edit_mesh= NULL;
+       
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
        if(mesh->mr) {
@@ -2653,11 +3061,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
                direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
                direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
                
-               if(mesh->mr->edge_flags)
-                       mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
-               if(mesh->mr->edge_creases)
-                       mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
-               
                if(!mesh->mr->edge_flags)
                        mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
                if(!mesh->mr->edge_creases)
@@ -2670,15 +3073,12 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
                        lvl->faces= newdataadr(fd, lvl->faces);
                        lvl->edges= newdataadr(fd, lvl->edges);
                        lvl->colfaces= newdataadr(fd, lvl->colfaces);
-                       lvl->edge_boundary_states= NULL;
-                       lvl->vert_face_map = lvl->vert_edge_map = NULL;
-                       lvl->map_mem= NULL;
                }
        }
        
        if((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && mesh->tface) {
                TFace *tf= mesh->tface;
-               int i;
+               unsigned int i;
 
                for (i=0; i< (mesh->pv ? mesh->pv->totface : mesh->totface); i++, tf++) {
                        SWITCH_INT(tf->col[0]);
@@ -2699,7 +3099,7 @@ static void lib_link_latt(FileData *fd, Main *main)
        while(lt) {
                if(lt->id.flag & LIB_NEEDLINK) {
                        
-                       lt->ipo= newlibadr_us(fd, lt->id.lib, lt->ipo);
+                       lt->ipo= newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX depreceated - old animation system
                        lt->key= newlibadr_us(fd, lt->id.lib, lt->key);
                        
                        lt->id.flag -= LIB_NEEDLINK;
@@ -2714,6 +3114,8 @@ static void direct_link_latt(FileData *fd, Lattice *lt)
        
        lt->dvert= newdataadr(fd, lt->dvert);
        direct_link_dverts(fd, lt->pntsu*lt->pntsv*lt->pntsw, lt->dvert);
+       
+       lt->editlatt= NULL;
 }
 
 
@@ -2748,11 +3150,16 @@ static void lib_link_object(FileData *fd, Main *main)
        while(ob) {
                if(ob->id.flag & LIB_NEEDLINK) {
                        if (ob->id.properties) IDP_LibLinkProperty(ob->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                       if (ob->adt) lib_link_animdata(fd, &ob->id, ob->adt);
+                       
+// XXX depreceated - old animation system <<<                  
+                       ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo);
+                       ob->action = newlibadr_us(fd, ob->id.lib, ob->action);
+// >>> XXX depreceated - old animation system
 
                        ob->parent= newlibadr(fd, ob->id.lib, ob->parent);
                        ob->track= newlibadr(fd, ob->id.lib, ob->track);
-                       ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo);
-                       ob->action = newlibadr_us(fd, ob->id.lib, ob->action);
+                       ob->poselib= newlibadr_us(fd, ob->id.lib, ob->poselib);
                        ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group);
                        
                        ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy);
@@ -2770,7 +3177,7 @@ static void lib_link_object(FileData *fd, Main *main)
                                }
                        }
                        ob->proxy_group= newlibadr(fd, ob->id.lib, ob->proxy_group);
-
+                       
                        poin= ob->data;
                        ob->data= newlibadr_us(fd, ob->id.lib, ob->data);
                           
@@ -2781,22 +3188,24 @@ static void lib_link_object(FileData *fd, Main *main)
                                else printf("Object %s lost data.", ob->id.name+2);
                                
                                if(ob->pose) {
-                                       free_pose_channels(ob->pose);
-                                       MEM_freeN(ob->pose);
+                                       free_pose(ob->pose);
                                        ob->pose= NULL;
                                        ob->flag &= ~OB_POSEMODE;
                                }
                        }
                        for(a=0; a<ob->totcol; a++) ob->mat[a]= newlibadr_us(fd, ob->id.lib, ob->mat[a]);
-
+                       
                        ob->id.flag -= LIB_NEEDLINK;
                        /* if id.us==0 a new base will be created later on */
-
+                       
                        /* WARNING! Also check expand_object(), should reflect the stuff below. */
                        lib_link_pose(fd, ob, ob->pose);
                        lib_link_constraints(fd, &ob->id, &ob->constraints);
-                       lib_link_nlastrips(fd, &ob->id, &ob->nlastrips);
+                       
+// XXX depreceated - old animation system <<<  
                        lib_link_constraint_channels(fd, &ob->id, &ob->constraintChannels);
+                       lib_link_nlastrips(fd, &ob->id, &ob->nlastrips);
+// >>> XXX depreceated - old animation system
 
                        for(paf= ob->effect.first; paf; paf= paf->next) {
                                if(paf->type==EFF_PARTICLE) {
@@ -2806,11 +3215,9 @@ static void lib_link_object(FileData *fd, Main *main)
 
                        sens= ob->sensors.first;
                        while(sens) {
-                               if(ob->id.lib==NULL) {  // done in expand_main
-                                       for(a=0; a<sens->totlinks; a++) {
-                                               sens->links[a]= newglobadr(fd, sens->links[a]);
-                                       }
-                               }
+                               for(a=0; a<sens->totlinks; a++)
+                                       sens->links[a]= newglobadr(fd, sens->links[a]);
+
                                if(sens->type==SENS_TOUCH) {
                                        bTouchSensor *ts= sens->data;
                                        ts->ma= newlibadr(fd, ob->id.lib, ts->ma);
@@ -2825,11 +3232,9 @@ static void lib_link_object(FileData *fd, Main *main)
 
                        cont= ob->controllers.first;
                        while(cont) {
-                               if(ob->id.lib==NULL) {  // done in expand_main
-                                       for(a=0; a<cont->totlinks; a++) {
-                                               cont->links[a]= newglobadr(fd, cont->links[a]);
-                                       }
-                               }
+                               for(a=0; a<cont->totlinks; a++)
+                                       cont->links[a]= newglobadr(fd, cont->links[a]);
+
                                if(cont->type==CONT_PYTHON) {
                                        bPythonCont *pc= cont->data;
                                        pc->text= newlibadr(fd, ob->id.lib, pc->text);
@@ -2880,6 +3285,10 @@ static void lib_link_object(FileData *fd, Main *main)
                                        bActionActuator *aa= act->data;
                                        aa->act= newlibadr(fd, ob->id.lib, aa->act);
                                }
+                               else if(act->type==ACT_SHAPEACTION) {
+                                       bActionActuator *aa= act->data;
+                                       aa->act= newlibadr(fd, ob->id.lib, aa->act);
+                               }
                                else if(act->type==ACT_PROPERTY) {
                                        bPropertyActuator *pa= act->data;
                                        pa->ob= newlibadr(fd, ob->id.lib, pa->ob);
@@ -2888,11 +3297,25 @@ static void lib_link_object(FileData *fd, Main *main)
                                        bMessageActuator *ma= act->data;
                                        ma->toObject= newlibadr(fd, ob->id.lib, ma->toObject);
                                }
+                               else if(act->type==ACT_2DFILTER){
+                                       bTwoDFilterActuator *_2dfa = act->data; 
+                                       _2dfa->text= newlibadr(fd, ob->id.lib, _2dfa->text);
+                               }
+                               else if(act->type==ACT_PARENT) {
+                                       bParentActuator *parenta = act->data; 
+                                       parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
+                               }
+                               else if(act->type==ACT_STATE) {
+                                       /* bStateActuator *statea = act->data; */
+                               }
                                act= act->next;
                        }
-
-                       if(ob->fluidsimSettings) {
-                               ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
+                       
+                       {
+                               FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+                               
+                               if(fluidmd && fluidmd->fss) 
+                                       fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, fluidmd->fss->ipo);
                        }
                        
                        /* texture field */
@@ -2901,24 +3324,26 @@ static void lib_link_object(FileData *fd, Main *main)
                                        ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex);
 
                        lib_link_scriptlink(fd, &ob->id, &ob->scriptlink);
-                       lib_link_particlesystems(fd, &ob->id, &ob->particlesystem);
+                       lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
                        lib_link_modifiers(fd, ob);
                }
                ob= ob->id.next;
        }
 
-       if(warn); //XXX error("WARNING IN CONSOLE");
+       if(warn)
+               BKE_report(fd->reports, RPT_WARNING, "Warning in console");
 }
 
 
-static void direct_link_pose(FileData *fd, bPose *pose) {
-
+static void direct_link_pose(FileData *fd, bPose *pose)
+{
        bPoseChannel *pchan;
 
        if (!pose)
                return;
 
        link_list(fd, &pose->chanbase);
+       link_list(fd, &pose->agroups);
 
        for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
                pchan->bone= NULL;
@@ -2928,7 +3353,6 @@ static void direct_link_pose(FileData *fd, bPose *pose) {
                pchan->iktree.first= pchan->iktree.last= NULL;
                pchan->path= NULL;
        }
-
 }
 
 static void direct_link_modifiers(FileData *fd, ListBase *lb)
@@ -2939,6 +3363,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 
        for (md=lb->first; md; md=md->next) {
                md->error = NULL;
+               md->scene = NULL;
                
                /* if modifiers disappear, or for upward compatibility */
                if(NULL==modifierType_getInfo(md->type))
@@ -2948,7 +3373,57 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        SubsurfModifierData *smd = (SubsurfModifierData*) md;
 
                        smd->emCache = smd->mCache = 0;
-               } else if (md->type==eModifierType_Hook) {
+               }
+               else if (md->type==eModifierType_Cloth) {
+                       ClothModifierData *clmd = (ClothModifierData*) md;
+                       
+                       clmd->clothObject = NULL;
+                       
+                       clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
+                       clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
+                       clmd->point_cache= newdataadr(fd, clmd->point_cache);
+
+                       if(clmd->point_cache)
+                               direct_link_pointcache(fd, clmd->point_cache);
+                       
+                       if(clmd->sim_parms) {
+                               if(clmd->sim_parms->presets > 10)
+                                       clmd->sim_parms->presets = 0;
+                       }
+                       
+               }
+               else if (md->type==eModifierType_Fluidsim) {
+                       FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
+                       
+                       fluidmd->fss= newdataadr(fd, fluidmd->fss);
+               }
+               else if (md->type==eModifierType_Collision) {
+                       
+                       CollisionModifierData *collmd = (CollisionModifierData*) md;
+                       /*
+                       // TODO: CollisionModifier should use pointcache 
+                       // + have proper reset events before enabling this
+                       collmd->x = newdataadr(fd, collmd->x);
+                       collmd->xnew = newdataadr(fd, collmd->xnew);
+                       collmd->mfaces = newdataadr(fd, collmd->mfaces);
+                       
+                       collmd->current_x = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_x");
+                       collmd->current_xnew = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_xnew");
+                       collmd->current_v = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_v");
+                       */
+                       
+                       collmd->x = NULL;
+                       collmd->xnew = NULL;
+                       collmd->current_x = NULL;
+                       collmd->current_xnew = NULL;
+                       collmd->current_v = NULL;
+                       collmd->time = -1;
+                       collmd->numverts = 0;
+                       collmd->bvhtree = NULL;
+                       collmd->mfaces = NULL;
+                       
+               }
+               else if (md->type==eModifierType_Hook) {
                        HookModifierData *hmd = (HookModifierData*) md;
 
                        hmd->indexar= newdataadr(fd, hmd->indexar);
@@ -2992,19 +3467,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                                SWITCH_INT(mmd->dynverts[a])
                        }
                }
+               else if (md->type==eModifierType_Multires) {
+                       MultiresModifierData *mmd = (MultiresModifierData*) md;
+                       
+                       mmd->undo_verts = newdataadr(fd, mmd->undo_verts);
+                       mmd->undo_signal = !!mmd->undo_verts;
+               }
        }
 }
 
-static void direct_link_nlastrips(FileData *fd, ListBase *strips)
-{
-       bActionStrip *strip;
-       
-       link_list(fd, strips);
-       
-       for(strip= strips->first; strip; strip= strip->next)
-               link_list(fd, &strip->modifiers);
-}
-
 static void direct_link_object(FileData *fd, Object *ob)
 {
        PartEff *paf;
@@ -3018,13 +3489,18 @@ static void direct_link_object(FileData *fd, Object *ob)
        ob->flag &= ~OB_FROMGROUP;
 
        ob->disp.first=ob->disp.last= NULL;
-
+       
+       ob->adt= newdataadr(fd, ob->adt);
+       direct_link_animdata(fd, ob->adt);
+       
        ob->pose= newdataadr(fd, ob->pose);
        direct_link_pose(fd, ob->pose);
 
        link_list(fd, &ob->defbase);
+// XXX depreceated - old animation system <<<
        direct_link_nlastrips(fd, &ob->nlastrips);
        link_list(fd, &ob->constraintChannels);
+// >>> XXX depreceated - old animation system 
 
        direct_link_scriptlink(fd, &ob->scriptlink);
 
@@ -3093,7 +3569,6 @@ static void direct_link_object(FileData *fd, Object *ob)
                sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
                sb->bspring= NULL;
                sb->scratch= NULL;
-
                /* although not used anymore */
                /* still have to be loaded to be compatible with old files */
                sb->keys= newdataadr(fd, sb->keys);
@@ -3103,15 +3578,13 @@ static void direct_link_object(FileData *fd, Object *ob)
                                sb->keys[a]= newdataadr(fd, sb->keys[a]);
                        }
                }
+
+               sb->pointcache= newdataadr(fd, sb->pointcache);
+               if(sb->pointcache)
+                       direct_link_pointcache(fd, sb->pointcache);
        }
+       ob->bsoft= newdataadr(fd, ob->bsoft);
        ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
-       if(ob->fluidsimSettings) {
-               // reinit mesh pointers
-               ob->fluidsimSettings->orgMesh = NULL; //ob->data;
-               ob->fluidsimSettings->meshSurface = NULL;
-               ob->fluidsimSettings->meshBB = NULL;
-               ob->fluidsimSettings->meshSurfNormals = NULL;
-       }
 
        link_list(fd, &ob->particlesystem);
        direct_link_particlesystems(fd,&ob->particlesystem);
@@ -3136,11 +3609,19 @@ static void direct_link_object(FileData *fd, Object *ob)
        direct_link_constraints(fd, &ob->constraints);
 
        link_glob_list(fd, &ob->controllers);
+       if (ob->init_state) {
+               /* if a known first state is specified, set it so that the game will start ok */
+               ob->state = ob->init_state;
+       } else if (!ob->state) {
+               ob->state = 1;
+       }
        cont= ob->controllers.first;
        while(cont) {
                cont->data= newdataadr(fd, cont->data);
                cont->links= newdataadr(fd, cont->links);
                test_pointer_array(fd, (void **)&cont->links);
+               if (cont->state_mask == 0)
+                       cont->state_mask = 1;
                cont= cont->next;
        }
 
@@ -3185,6 +3666,7 @@ static void direct_link_object(FileData *fd, Object *ob)
        ob->bb= NULL;
        ob->derivedDeform= NULL;
        ob->derivedFinal= NULL;
+       ob->gpulamp.first= ob->gpulamp.last= NULL;
 }
 
 /* ************ READ SCENE ***************** */
@@ -3193,10 +3675,8 @@ static void lib_link_scene(FileData *fd, Main *main)
 {
        Scene *sce;
        Base *base, *next;
-       Editing *ed;
        Sequence *seq;
        SceneRenderLayer *srl;
-       int a;
        
        sce= main->scene.first;
        while(sce) {
@@ -3204,20 +3684,17 @@ static void lib_link_scene(FileData *fd, Main *main)
                        /*Link ID Properties -- and copy this comment EXACTLY for easy finding
                        of library blocks that implement this.*/
                        if (sce->id.properties) IDP_LibLinkProperty(sce->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-
+                       if (sce->adt) lib_link_animdata(fd, &sce->id, sce->adt);
+                       
                        sce->camera= newlibadr(fd, sce->id.lib, sce->camera);
                        sce->world= newlibadr_us(fd, sce->id.lib, sce->world);
                        sce->set= newlibadr(fd, sce->id.lib, sce->set);
                        sce->ima= newlibadr_us(fd, sce->id.lib, sce->ima);
                        sce->toolsettings->imapaint.brush=
                                newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.brush);
-
-                       /* Sculptdata textures */
-                       for(a=0; a<MAX_MTEX; ++a) {
-                               MTex *mtex= sce->sculptdata.mtex[a];
-                               if(mtex)
-                                       mtex->tex= newlibadr_us(fd, sce->id.lib, mtex->tex);
-                       }
+                       if(sce->toolsettings->sculpt)
+                               sce->toolsettings->sculpt->brush=
+                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->sculpt->brush);
 
                        for(base= sce->base.first; base; base= next) {
                                next= base->next;
@@ -3235,24 +3712,26 @@ static void lib_link_scene(FileData *fd, Main *main)
                                        MEM_freeN(base);
                                }
                        }
-
-                       ed= sce->ed;
-                       if(ed) {
-                               WHILE_SEQ(&ed->seqbase) { //XXX todo replace WHILE_SEQ
-                                       if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
-                                       if(seq->scene) seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
-                                       if(seq->sound) {
-                                               seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
-                                               if (seq->sound) {
-                                                       seq->sound->id.us++;
-                                                       seq->sound->flags |= SOUND_FLAGS_SEQUENCE;
-                                               }
+                       
+                       if (sce->ed) {
+                               Editing *ed= sce->ed;
+                               ed->act_seq= NULL; //   ed->act_seq=  newlibadr(fd, ed->act_seq); // FIXME
+                       }
+
+                       SEQ_BEGIN(sce->ed, seq) {
+                               if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
+                               if(seq->scene) seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
+                               if(seq->sound) {
+                                       seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
+                                       if (seq->sound) {
+                                               seq->sound->id.us++;
+                                               seq->sound->flags |= SOUND_FLAGS_SEQUENCE;
                                        }
-                                       seq->anim= 0;
-                                       seq->hdaudio = 0;
                                }
-                               END_SEQ
+                               seq->anim= 0;
+                               seq->hdaudio = 0;
                        }
+                       SEQ_END
                        
                        lib_link_scriptlink(fd, &sce->id, &sce->scriptlink);
                        
@@ -3276,11 +3755,10 @@ static void link_recurs_seq(FileData *fd, ListBase *lb)
        Sequence *seq;
 
        link_list(fd, lb);
-       seq= lb->first;
-       while(seq) {
-               if(seq->seqbase.first) link_recurs_seq(fd, &seq->seqbase);
-               seq= seq->next;
-       }
+
+       for(seq=lb->first; seq; seq=seq->next)
+               if(seq->seqbase.first)
+                       link_recurs_seq(fd, &seq->seqbase);
 }
 
 static void direct_link_scene(FileData *fd, Scene *sce)
@@ -3288,7 +3766,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
-       int a;
 
        sce->theDag = NULL;
        sce->dagisvalid = 0;
@@ -3296,33 +3773,33 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        sce->id.us= 1;
 
        link_list(fd, &(sce->base));
-
+       
+       sce->adt= newdataadr(fd, sce->adt);
+       direct_link_animdata(fd, sce->adt);
+       
        sce->basact= newdataadr(fd, sce->basact);
 
        sce->radio= newdataadr(fd, sce->radio);
        
        sce->toolsettings= newdataadr(fd, sce->toolsettings);
-
-       sce->sculptdata.session= NULL;
-       /* SculptData textures */
-       for(a=0; a<MAX_MTEX; ++a)
-               sce->sculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]);
-       /* Sculpt intensity curve */
-       sce->sculptdata.cumap= newdataadr(fd, sce->sculptdata.cumap);
-       if(sce->sculptdata.cumap)
-               direct_link_curvemapping(fd, sce->sculptdata.cumap);
-       else
-               ; //XXX sculpt_reset_curve(&sce->sculptdata);
+       if(sce->toolsettings) {
+               sce->toolsettings->vpaint= newdataadr(fd, sce->toolsettings->vpaint);
+               sce->toolsettings->wpaint= newdataadr(fd, sce->toolsettings->wpaint);
+               sce->toolsettings->sculpt= newdataadr(fd, sce->toolsettings->sculpt);
+               if(sce->toolsettings->sculpt)
+                       sce->toolsettings->sculpt->session= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
+       }
 
        if(sce->ed) {
                ListBase *old_seqbasep= &((Editing *)sce->ed)->seqbase;
                
                ed= sce->ed= newdataadr(fd, sce->ed);
+               ed->act_seq= NULL; //           ed->act_seq=  newdataadr(fd, ed->act_seq); // FIXME
 
                /* recursive link sequences, lb will be correctly initialized */
                link_recurs_seq(fd, &ed->seqbase);
 
-               WHILE_SEQ(&ed->seqbase) { //XXX todo replace WHILE_SEQ
+               SEQ_BEGIN(ed, seq) {
                        seq->seq1= newdataadr(fd, seq->seq1);
                        seq->seq2= newdataadr(fd, seq->seq2);
                        seq->seq3= newdataadr(fd, seq->seq3);
@@ -3340,6 +3817,10 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                        if(seq->strip && seq->strip->done==0) {
                                seq->strip->done= 1;
                                seq->strip->tstripdata = 0;
+                               seq->strip->tstripdata_startstill = 0;
+                               seq->strip->tstripdata_endstill = 0;
+                               seq->strip->ibuf_startstill = 0;
+                               seq->strip->ibuf_endstill = 0;
 
                                if(seq->type == SEQ_IMAGE ||
                                   seq->type == SEQ_MOVIE ||
@@ -3350,17 +3831,41 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                                } else {
                                        seq->strip->stripdata = 0;
                                }
+                               if (seq->flag & SEQ_USE_CROP) {
+                                       seq->strip->crop = newdataadr(
+                                               fd, seq->strip->crop);
+                               } else {
+                                       seq->strip->crop = 0;
+                               }
+                               if (seq->flag & SEQ_USE_TRANSFORM) {
+                                       seq->strip->transform = newdataadr(
+                                               fd, seq->strip->transform);
+                               } else {
+                                       seq->strip->transform = 0;
+                               }
+                               if (seq->flag & SEQ_USE_PROXY) {
+                                       seq->strip->proxy = newdataadr(
+                                               fd, seq->strip->proxy);
+                               } else {
+                                       seq->strip->proxy = 0;
+                               }
+                               if (seq->flag & SEQ_USE_COLOR_BALANCE) {
+                                       seq->strip->color_balance = newdataadr(
+                                               fd, seq->strip->color_balance);
+                               } else {
+                                       seq->strip->color_balance = 0;
+                               }
                        }
                }
-               END_SEQ
+               SEQ_END
                
                /* link metastack, slight abuse of structs here, have to restore pointer to internal part in struct */
                {
                        Sequence temp;
                        char *poin;
-                       long offset;
+                       intptr_t offset;
                        
-                       offset= ((long)&(temp.seqbase)) - ((long)&temp);
+                       offset= ((intptr_t)&(temp.seqbase)) - ((intptr_t)&temp);
                        
                        /* root pointer */
                        if(ed->seqbasep == old_seqbasep) {
@@ -3406,8 +3911,18 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        if (sce->r.qtcodecdata) {
                sce->r.qtcodecdata->cdParms = newdataadr(fd, sce->r.qtcodecdata->cdParms);
        }
-       
+       if (sce->r.ffcodecdata.properties) {
+               sce->r.ffcodecdata.properties = newdataadr(
+                       fd, sce->r.ffcodecdata.properties);
+               if (sce->r.ffcodecdata.properties) { 
+                       IDP_DirectLinkProperty(
+                               sce->r.ffcodecdata.properties, 
+                               (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               }
+       }
+
        link_list(fd, &(sce->markers));
+       link_list(fd, &(sce->transform_spaces));
        link_list(fd, &(sce->r.layers));
        
        sce->nodetree= newdataadr(fd, sce->nodetree);
@@ -3424,32 +3939,29 @@ static void direct_link_scene(FileData *fd, Scene *sce)
 
    This is needed, to make Ipo-Pinning work for Sequence-Ipos...
 */
+// XXX old animation system - depreceated stuff...
 static Sequence * find_sequence_from_ipo_helper(Main * main, Ipo * ipo)
 {
-       Editing *ed;
-       Sequence *seq = NULL;
-
-       Scene * sce= main->scene.first;
-       while(sce) {
-               if(sce->ed) {
-                       int found = 0;
-
-                       ed= sce->ed;
+       Sequence *seq;
+       Scene *sce;
+       
+       for(sce=main->scene.first; sce; sce=sce->id.next) {
+               int found = 0;
 
-                       WHILE_SEQ(&ed->seqbase) { //XXX todo replace WHILE_SEQ
-                               if (seq->ipo == ipo) {
-                                       found = 1;
-                                       break;
-                               }
-                       } 
-                       END_SEQ
-                       if (found) {
+               SEQ_BEGIN(sce->ed, seq) {
+                       if (seq->ipo == ipo) {
+                               found = 1;
                                break;
                        }
-                       seq = NULL;
+               } 
+               SEQ_END
+
+               if (found) {
+                       break;
                }
-               sce= sce->id.next;
+               seq = NULL;
        }
+
        if (seq)
         return seq;
        else
@@ -3490,15 +4002,18 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
                win->eventstate= NULL;
                win->curswin= NULL;
                
+               win->timers.first= win->timers.last= NULL;
                win->queue.first= win->queue.last= NULL;
                win->handlers.first= win->handlers.last= NULL;
                win->subwindows.first= win->subwindows.last= NULL;
+
+               win->drawtex= 0;
+               win->drawmethod= 0;
        }
        
        wm->operators.first= wm->operators.last= NULL;
-       wm->windowkeymap.first= wm->windowkeymap.last= NULL;
-       wm->screenkeymap.first= wm->screenkeymap.last= NULL;
-       
+       wm->keymaps.first= wm->keymaps.last= NULL;
+       wm->paintcursors.first= wm->paintcursors.last= NULL;
        wm->queue.first= wm->queue.last= NULL;
        wm->reports.first= wm->reports.last= NULL;
        
@@ -3518,7 +4033,56 @@ static void lib_link_windowmanager(FileData *fd, Main *main)
        }
 }
 
-/* ************ READ SCREEN ***************** */
+/* ****************** READ GREASE PENCIL ***************** */
+
+/* relinks grease-pencil data for 3d-view(s) - used for direct_link */
+static void link_gpencil(FileData *fd, bGPdata *gpd)
+{
+       bGPDlayer *gpl;
+       bGPDframe *gpf;
+       bGPDstroke *gps;
+       
+       /* relink layers */
+       link_list(fd, &gpd->layers);
+       
+       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+               /* relink frames */
+               link_list(fd, &gpl->frames);
+               gpl->actframe= newdataadr(fd, gpl->actframe);
+               
+               for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+                       /* relink strokes (and their points) */
+                       link_list(fd, &gpf->strokes);
+                       
+                       for (gps= gpf->strokes.first; gps; gps= gps->next) {
+                               gps->points= newdataadr(fd, gps->points);
+                       }
+               }
+       }
+}
+
+/* ****************** READ SCREEN ***************** */
+
+static void butspace_version_132(SpaceButs *buts)
+{
+       buts->v2d.tot.xmin= 0.0f;
+       buts->v2d.tot.ymin= 0.0f;
+       buts->v2d.tot.xmax= 1279.0f;
+       buts->v2d.tot.ymax= 228.0f;
+
+       buts->v2d.min[0]= 256.0f;
+       buts->v2d.min[1]= 42.0f;
+
+       buts->v2d.max[0]= 2048.0f;
+       buts->v2d.max[1]= 450.0f;
+
+       buts->v2d.minzoom= 0.5f;
+       buts->v2d.maxzoom= 1.21f;
+
+       buts->v2d.scroll= 0;
+       buts->v2d.keepzoom= 1;
+       buts->v2d.keeptot= 1;
+}
 
 /* note: file read without screens option G_FILE_NO_UI; 
    check lib pointers in call below */
@@ -3531,31 +4095,29 @@ static void lib_link_screen(FileData *fd, Main *main)
                if(sc->id.flag & LIB_NEEDLINK) {
                        sc->id.us= 1;
                        sc->scene= newlibadr(fd, sc->id.lib, sc->scene);
-
+                       
                        sa= sc->areabase.first;
                        while(sa) {
                                SpaceLink *sl;
-
+                               
                                sa->full= newlibadr(fd, sc->id.lib, sa->full);
-
+                               
                                /* space handler scriptlinks */
                                lib_link_scriptlink(fd, &sc->id, &sa->scriptlink);
-
+                               
                                for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                        if(sl->spacetype==SPACE_VIEW3D) {
                                                View3D *v3d= (View3D*) sl;
-
+                                               
                                                v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera);
                                                v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre);
-
+                                               
                                                if(v3d->bgpic) {
                                                        v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
                                                }
                                                if(v3d->localvd) {
                                                        v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
                                                }
-                                               v3d->depths= NULL;
-                                               v3d->ri= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_IPO) {
                                                SpaceIpo *sipo= (SpaceIpo *)sl;
@@ -3571,16 +4133,17 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                SpaceButs *sbuts= (SpaceButs *)sl;
                                                sbuts->lockpoin= NULL;
                                                sbuts->ri= NULL;
-// XXX                                         if(main->versionfile<132) set_rects_butspace(sbuts);
+                                               if(main->versionfile<132)
+                                                       butspace_version_132(sbuts);
                                        }
                                        else if(sl->spacetype==SPACE_FILE) {
                                                SpaceFile *sfile= (SpaceFile *)sl;
-
-                                               sfile->filelist= NULL;
-                                               sfile->libfiledata= NULL;
-                                               sfile->returnfunc= NULL;
+                                               sfile->files= NULL;
+                                               sfile->params= NULL;
+                                               sfile->op= NULL;
+                                               /* sfile->returnfunc= NULL; 
                                                sfile->menup= NULL;
-                                               sfile->pupmenu= NULL;
+                                               sfile->pupmenu= NULL; */ /* XXX removed */
                                        }
                                        else if(sl->spacetype==SPACE_IMASEL) {
                                                SpaceImaSel *simasel= (SpaceImaSel *)sl;
@@ -3594,6 +4157,7 @@ static void lib_link_screen(FileData *fd, Main *main)
                                        else if(sl->spacetype==SPACE_ACTION) {
                                                SpaceAction *saction= (SpaceAction *)sl;
                                                saction->action = newlibadr(fd, sc->id.lib, saction->action);
+                                               saction->ads.source= newlibadr(fd, sc->id.lib, saction->ads.source);
                                        }
                                        else if(sl->spacetype==SPACE_IMAGE) {
                                                SpaceImage *sima= (SpaceImage *)sl;
@@ -3610,9 +4174,15 @@ static void lib_link_screen(FileData *fd, Main *main)
 
                                        }
                                        else if(sl->spacetype==SPACE_SCRIPT) {
-                                               SpaceScript *sc= (SpaceScript *)sl;
 
-                                               sc->script = NULL;
+                                               SpaceScript *scpt= (SpaceScript *)sl;
+                                               /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
+                                               if (scpt->script) {
+                                                       scpt->script= newlibadr(fd, sc->id.lib, scpt->script);
+                                                       if (scpt->script) {
+                                                               SCRIPT_SET_NULL(scpt->script)
+                                                       }
+                                               }
                                        }
                                        else if(sl->spacetype==SPACE_OOPS) {
                                                SpaceOops *so= (SpaceOops *)sl;
@@ -3678,14 +4248,31 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
 /* called from kernel/blender.c */
 /* used to link a file (without UI) to the current UI */
 /* note that it assumes the old pointers in UI are still valid, so old Main is not freed */
-void lib_link_screen_restore(Main *newmain, Scene *curscene)
+void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
 {
+       wmWindow *win;
+       wmWindowManager *wm;
        bScreen *sc;
        ScrArea *sa;
 
+       /* first windowmanager */
+       for(wm= newmain->wm.first; wm; wm= wm->id.next) {
+               for(win= wm->windows.first; win; win= win->next) {
+                       win->screen= restore_pointer_by_name(newmain, (ID *)win->screen, 1);
+                       
+                       if(win->screen==NULL)
+                               win->screen= curscreen;
+
+                       win->screen->winid= win->winid;
+               }
+       }
+       
+       
        for(sc= newmain->screen.first; sc; sc= sc->id.next) {
                
-               sc->scene= curscene;
+               sc->scene= restore_pointer_by_name(newmain, (ID *)sc->scene, 1);
+               if(sc->scene==NULL)
+                       sc->scene= curscene;
 
                sa= sc->areabase.first;
                while(sa) {
@@ -3753,10 +4340,16 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                        //XXX if (sbuts->ri) sbuts->ri->curtile = 0;
                                }
                                else if(sl->spacetype==SPACE_FILE) {
+                                       
                                        SpaceFile *sfile= (SpaceFile *)sl;
+                                       sfile->files= NULL;
+                                       sfile->params= NULL;
+                                       sfile->op= NULL;
+                                       /* XXX needs checking - best solve in filesel itself 
                                        if(sfile->libfiledata)  
                                                BLO_blendhandle_close(sfile->libfiledata);
                                        sfile->libfiledata= 0;
+                                       */
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
                     SpaceImaSel *simasel= (SpaceImaSel *)sl;
@@ -3767,6 +4360,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                else if(sl->spacetype==SPACE_ACTION) {
                                        SpaceAction *saction= (SpaceAction *)sl;
                                        saction->action = restore_pointer_by_name(newmain, (ID *)saction->action, 1);
+                                       saction->ads.source= restore_pointer_by_name(newmain, (ID *)saction->ads.source, 1);
                                }
                                else if(sl->spacetype==SPACE_IMAGE) {
                                        SpaceImage *sima= (SpaceImage *)sl;
@@ -3783,10 +4377,15 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                        if(st->text==NULL) st->text= newmain->text.first;
                                }
                                else if(sl->spacetype==SPACE_SCRIPT) {
-                                       SpaceScript *sc= (SpaceScript *)sl;
-
-                                       sc->script = NULL;
-                               }
+                                       SpaceScript *scpt= (SpaceScript *)sl;
+                                       
+                                       scpt->script= restore_pointer_by_name(newmain, (ID *)scpt->script, 1);
+                                       
+                                       /*sc->script = NULL; - 2.45 set to null, better re-run the script */
+                                       if (scpt->script) {
+                                               SCRIPT_SET_NULL(scpt->script)
+                                       }
+                               }
                                else if(sl->spacetype==SPACE_OOPS) {
                                        SpaceOops *so= (SpaceOops *)sl;
                                        Oops *oops;
@@ -3825,6 +4424,64 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
        }
 }
 
+static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
+{
+       Panel *pa;
+
+       link_list(fd, &(ar->panels));
+
+       for(pa= ar->panels.first; pa; pa=pa->next) {
+               pa->paneltab= newdataadr(fd, pa->paneltab);
+               pa->active= 0;
+               pa->sortcounter= 0;
+               pa->activedata= NULL;
+       }
+       
+       ar->regiondata= newdataadr(fd, ar->regiondata);
+       if(ar->regiondata) {
+               if(spacetype==SPACE_VIEW3D) {
+                       RegionView3D *rv3d= ar->regiondata;
+                       
+                       rv3d->localvd= newdataadr(fd, rv3d->localvd);
+                       rv3d->clipbb= newdataadr(fd, rv3d->clipbb);
+                       
+                       rv3d->depths= NULL;
+                       rv3d->retopo_view_data= NULL;
+                       rv3d->ri= NULL;
+                       rv3d->sms= NULL;
+                       rv3d->smooth_timer= NULL;
+               }
+       }
+       
+       ar->handlers.first= ar->handlers.last= NULL;
+       ar->uiblocks.first= ar->uiblocks.last= NULL;
+       ar->headerstr= NULL;
+       ar->swinid= 0;
+       ar->type= NULL;
+       ar->swap= 0;
+}
+
+/* for the saved 2.50 files without regiondata */
+/* and as patch for 2.48 and older */
+static void view3d_split_250(View3D *v3d, ListBase *regions)
+{
+       ARegion *ar;
+       
+       for(ar= regions->first; ar; ar= ar->next) {
+               if(ar->regiontype==RGN_TYPE_WINDOW && ar->regiondata==NULL) {
+                       RegionView3D *rv3d;
+                       
+                       rv3d= ar->regiondata= MEM_callocN(sizeof(RegionView3D), "region v3d");
+                       rv3d->persp= v3d->persp;
+                       rv3d->view= v3d->view;
+                       rv3d->dist= v3d->dist;
+                       VECCOPY(rv3d->ofs, v3d->ofs);
+                       QUATCOPY(rv3d->viewquat, v3d->viewquat);
+                       Mat4One(rv3d->twmat);
+               }
+       }
+}
+
 static void direct_link_screen(FileData *fd, bScreen *sc)
 {
        ScrArea *sa;
@@ -3836,7 +4493,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
        link_list(fd, &(sc->vertbase));
        link_list(fd, &(sc->edgebase));
        link_list(fd, &(sc->areabase));
-       
+       sc->regionbase.first= sc->regionbase.last= NULL;
+       sc->context= NULL;
+
        sc->mainwin= sc->subwinactive= 0;       /* indices */
        
        /* hacky patch... but people have been saving files with the verse-blender,
@@ -3852,7 +4511,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
        for(se= sc->edgebase.first; se; se= se->next) {
                se->v1= newdataadr(fd, se->v1);
                se->v2= newdataadr(fd, se->v2);
-               if( (long)se->v1 > (long)se->v2) {
+               if( (intptr_t)se->v1 > (intptr_t)se->v2) {
                        sv= se->v1;
                        se->v1= se->v2;
                        se->v2= sv;
@@ -3866,39 +4525,49 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
 
        /* areas */
        for(sa= sc->areabase.first; sa; sa= sa->next) {
-               Panel *pa;
                SpaceLink *sl;
                ARegion *ar;
 
                link_list(fd, &(sa->spacedata));
-               link_list(fd, &(sa->panels));
                link_list(fd, &(sa->regionbase));
 
                sa->handlers.first= sa->handlers.last= NULL;
-               sa->uiblocks.first= sa->uiblocks.last= NULL;
                sa->type= NULL; /* spacetype callbacks */
                
-               /* accident can happen when read/save new file with older version */
-               if(sa->spacedata.first==NULL && sa->spacetype>SPACE_NLA)
-                       sa->spacetype= SPACE_EMPTY;
+               for(ar= sa->regionbase.first; ar; ar= ar->next)
+                       direct_link_region(fd, ar, sa->spacetype);
                
-               for(pa= sa->panels.first; pa; pa=pa->next) {
-                       pa->paneltab= newdataadr(fd, pa->paneltab);
-                       pa->active= 0;
-                       pa->sortcounter= 0;
-               }
+               /* accident can happen when read/save new file with older version */
+               /* 2.50: we now always add spacedata for info */
+               if(sa->spacedata.first==NULL) {
+                       SpaceInfo *sinfo= MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
+                       sa->spacetype= SPACE_INFO;
+                       BLI_addtail(&sa->spacedata, sinfo);
+               }
+               /* add local view3d too */
+               else if(sa->spacetype==SPACE_VIEW3D)
+                       view3d_split_250(sa->spacedata.first, &sa->regionbase);
                
                for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                       link_list(fd, &(sl->regionbase));
+
+                       for(ar= sl->regionbase.first; ar; ar= ar->next)
+                               direct_link_region(fd, ar, sl->spacetype);
+
                        if (sl->spacetype==SPACE_VIEW3D) {
                                View3D *v3d= (View3D*) sl;
                                v3d->bgpic= newdataadr(fd, v3d->bgpic);
                                if(v3d->bgpic)
                                        v3d->bgpic->iuser.ok= 1;
+                               if(v3d->gpd) {
+                                       v3d->gpd= newdataadr(fd, v3d->gpd);
+                                       link_gpencil(fd, v3d->gpd);
+                               }
                                v3d->localvd= newdataadr(fd, v3d->localvd);
                                v3d->afterdraw.first= v3d->afterdraw.last= NULL;
-                               v3d->clipbb= newdataadr(fd, v3d->clipbb);
-                               v3d->retopo_view_data= NULL;
                                v3d->properties_storage= NULL;
+                               
+                               view3d_split_250(v3d, &sl->regionbase);
                        }
                        else if (sl->spacetype==SPACE_OOPS) {
                                SpaceOops *soops= (SpaceOops*) sl;
@@ -3924,21 +4593,28 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                sima->cumap= newdataadr(fd, sima->cumap);
                                if(sima->cumap)
                                        direct_link_curvemapping(fd, sima->cumap);
-                               sima->info_str= sima->info_spare= NULL;
-                               sima->spare= NULL;
+                               sima->gpd= newdataadr(fd, sima->gpd);
+                               if (sima->gpd)
+                                       link_gpencil(fd, sima->gpd);
                                sima->iuser.ok= 1;
                        }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
+                               
+                               if(snode->gpd) {
+                                       snode->gpd= newdataadr(fd, snode->gpd);
+                                       link_gpencil(fd, snode->gpd);
+                               }
                                snode->nodetree= snode->edittree= NULL;
                                snode->flag |= SNODE_DO_PREVIEW;
                        }
-               }
-               
-               for(ar= sa->regionbase.first; ar; ar= ar->next) {
-                       ar->handlers.first= ar->handlers.last= NULL;
-                       ar->swinid= 0;
-                       ar->type= NULL;
+                       else if(sl->spacetype==SPACE_SEQ) {
+                               SpaceSeq *sseq= (SpaceSeq *)sl;
+                               if(sseq->gpd) {
+                                       sseq->gpd= newdataadr(fd, sseq->gpd);
+                                       link_gpencil(fd, sseq->gpd);
+                               }
+                       }
                }
                
                sa->actionzones.first= sa->actionzones.last= NULL;
@@ -3971,7 +4647,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
                                BLI_remlink(&main->library, lib);
                                MEM_freeN(lib);
                                
-                               //XXX error("Library had multiple instances, save and reload!");
+                               BKE_report(fd->reports, RPT_WARNING, "Library had multiple instances, save and reload!");
+
                                return;
                        }
                }
@@ -3994,11 +4671,26 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
 static void lib_link_library(FileData *fd, Main *main)
 {
        Library *lib;
-
-       lib= main->library.first;
-       while(lib) {
+       for(lib= main->library.first; lib; lib= lib->id.next) {
                lib->id.us= 1;
-               lib= lib->id.next;
+       }
+}
+
+/* Always call this once you havbe loaded new library data to set the relative paths correctly in relation to the blend file */
+static void fix_relpaths_library(const char *basepath, Main *main)
+{
+       Library *lib;
+       /* BLO_read_from_memory uses a blank filename */
+       if (basepath==NULL || basepath[0] == '\0')
+               return;
+               
+       for(lib= main->library.first; lib; lib= lib->id.next) {
+               /* Libraries store both relative and abs paths, recreate relative paths,
+                * relative to the blend file since indirectly linked libs will be relative to their direct linked library */
+               if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */
+                       strncpy(lib->name, lib->filename, sizeof(lib->name));
+                       BLI_makestringcode(basepath, lib->name);
+               }
        }
 }
 
@@ -4021,7 +4713,7 @@ static void lib_link_sound(FileData *fd, Main *main)
        while(sound) {
                if(sound->id.flag & LIB_NEEDLINK) {
                        sound->id.flag -= LIB_NEEDLINK;
-                       sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo);
+                       sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system
                        sound->stream = 0;
                }
                sound= sound->id.next;
@@ -4149,9 +4841,20 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        allocname= dataname(GS(id->name));
        
                /* read all data */
+       
        while(bhead && bhead->code==DATA) {
-               void *data= read_struct(fd, bhead, allocname);
-
+               void *data;
+#if 0          
+               /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */         
+               short *sp= fd->filesdna->structs[bhead->SDNAnr];
+               char *allocname = fd->filesdna->types[ sp[0] ];
+               char *tmp= malloc(100);
+               
+               strcpy(tmp, allocname);
+               data= read_struct(fd, bhead, tmp);
+#endif
+               data= read_struct(fd, bhead, allocname);
+               
                if (data) {
                        oldnewmap_insert(fd->datamap, bhead->old, data, 0);
                }
@@ -4239,12 +4942,17 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                case ID_PA:
                        direct_link_particlesettings(fd, (ParticleSettings*)id);
                        break;
+               case ID_SCRIPT:
+                       direct_link_script(fd, (Script*)id);
+                       break;
        }
        
        /*link direct data of ID properties*/
        if (id->properties) {
                id->properties = newdataadr(fd, id->properties);
-               IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               if (id->properties) { /* this case means the data was written incorrectly, it should not happen */
+                       IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               }
        }
 
        oldnewmap_free_unused(fd->datamap);
@@ -4315,19 +5023,19 @@ static void vcol_to_fcol(Mesh *me)
 static int map_223_keybd_code_to_224_keybd_code(int code)
 {
        switch (code) {
-//XXX  case 312:       return F12KEY;
-//XXX          case 159:       return PADSLASHKEY;
-//XXX          case 161:       return PAD0;
-//XXX          case 154:       return PAD1;
-//XXX          case 150:       return PAD2;
-//XXX          case 155:       return PAD3;
-//XXX          case 151:       return PAD4;
-//XXX          case 156:       return PAD5;
-//XXX          case 152:       return PAD6;
-//XXX          case 157:       return PAD7;
-//XXX          case 153:       return PAD8;
-//XXX          case 158:       return PAD9;
-       default: return code;
+               case 312:       return 311; /* F12KEY */
+               case 159:       return 161; /* PADSLASHKEY */
+               case 161:       return 150; /* PAD0 */
+               case 154:       return 151; /* PAD1 */
+               case 150:       return 152; /* PAD2 */
+               case 155:       return 153; /* PAD3 */
+               case 151:       return 154; /* PAD4 */
+               case 156:       return 155; /* PAD5 */
+               case 152:       return 156; /* PAD6 */
+               case 157:       return 157; /* PAD7 */
+               case 153:       return 158; /* PAD8 */
+               case 158:       return 159; /* PAD9 */
+               default: return code;
        }
 }
 
@@ -4560,29 +5268,371 @@ static void do_version_ntree_242_2(bNodeTree *ntree)
        }
 }
 
+static void ntree_version_245(FileData *fd, Library *lib, bNodeTree *ntree)
+{
+       bNode *node;
+       NodeTwoFloats *ntf;
+       ID *nodeid;
+       Image *image;
+       ImageUser *iuser;
+
+       if(ntree->type==NTREE_COMPOSIT) {
+               for(node= ntree->nodes.first; node; node= node->next) {
+                       if(node->type == CMP_NODE_ALPHAOVER) {
+                               if(!node->storage) {
+                                       ntf= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats");
+                                       node->storage= ntf;
+                                       if(node->custom1)
+                                               ntf->x= 1.0f;
+                               }
+                       }
+                       
+                       /* fix for temporary flag changes during 245 cycle */
+                       nodeid= newlibadr(fd, lib, node->id);
+                       if(node->storage && nodeid && GS(nodeid->name) == ID_IM) {
+                               image= (Image*)nodeid;
+                               iuser= node->storage;
+                               if(iuser->flag & IMA_OLD_PREMUL) {
+                                       iuser->flag &= ~IMA_OLD_PREMUL;
+                                       iuser->flag |= IMA_DO_PREMUL;
+                               }
+                               if(iuser->flag & IMA_DO_PREMUL) {
+                                       image->flag &= ~IMA_OLD_PREMUL;
+                                       image->flag |= IMA_DO_PREMUL;
+                               }
+                       }
+               }
+       }
+}
+
+static void idproperties_fix_groups_lengths_recurse(IDProperty *prop)
+{
+       IDProperty *loop;
+       int i;
+       
+       for (loop=prop->data.group.first, i=0; loop; loop=loop->next, i++) {
+               if (loop->type == IDP_GROUP) idproperties_fix_groups_lengths_recurse(loop);
+       }
+       
+       if (prop->len != i) {
+               printf("Found and fixed bad id property group length.\n");
+               prop->len = i;
+       }
+}
+
+static void idproperties_fix_group_lengths(ListBase idlist)
+{
+       ID *id;
+       
+       for (id=idlist.first; id; id=id->next) {
+               if (id->properties) {
+                       idproperties_fix_groups_lengths_recurse(id->properties);
+               }
+       }
+}
+
+static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
+{
+       Material *ma;
+       MFace *mf;
+       MTFace *tf;
+       int a, b, texalpha;
+
+       /* verify we have a tface layer */
+       for(b=0; b<me->fdata.totlayer; b++)
+               if(me->fdata.layers[b].type == CD_MTFACE)
+                       break;
+       
+       if(b == me->fdata.totlayer)
+               return;
+
+       /* if we do, set alpha sort if the game engine did it before */
+       for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+               if(mf->mat_nr < me->totcol) {
+                       ma= newlibadr(fd, lib, me->mat[(int)mf->mat_nr]);
+                       texalpha = 0;
+
+                       /* we can't read from this if it comes from a library,
+                        * because direct_link might not have happened on it,
+                        * so ma->mtex is not pointing to valid memory yet */
+                       if(ma && ma->id.lib)
+                               ma= NULL;
+
+                       for(b=0; ma && b<MAX_MTEX; b++)
+                               if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
+                                       texalpha = 1;
+               }
+               else {
+                       ma= NULL;
+                       texalpha = 0;
+               }
+
+               for(b=0; b<me->fdata.totlayer; b++) {
+                       if(me->fdata.layers[b].type == CD_MTFACE) {
+                               tf = ((MTFace*)me->fdata.layers[b].data) + a;
+
+                               tf->mode &= ~TF_ALPHASORT;
+                               if(ma && (ma->mode & MA_ZTRA))
+                                       if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP)))
+                                               tf->mode |= TF_ALPHASORT;
+                       }
+               }
+       }
+}
+
+/* 2.50 patch */
+static void area_add_header_region(ScrArea *sa, ListBase *lb)
+{
+       ARegion *ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+       
+       BLI_addtail(lb, ar);
+       ar->regiontype= RGN_TYPE_HEADER;
+       if(sa->headertype==1)
+               ar->alignment= RGN_ALIGN_BOTTOM;
+       else
+               ar->alignment= RGN_ALIGN_TOP;
+       
+       /* initialise view2d data for header region, to allow panning */
+       /* is copy from ui_view2d.c */
+       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+       ar->v2d.keepofs = V2D_LOCKOFS_Y;
+       ar->v2d.keeptot = V2D_KEEPTOT_STRICT; 
+       ar->v2d.align = V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_NEG_Y;
+       ar->v2d.flag = (V2D_PIXELOFS_X|V2D_PIXELOFS_Y);
+}
+
+/* 2.50 patch */
+static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
+{
+       ARegion *ar;
+       
+       if(sl) {
+               /* first channels for ipo action nla... */
+               switch(sl->spacetype) {
+                       case SPACE_IPO:
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_CHANNELS;
+                               ar->alignment= RGN_ALIGN_LEFT; 
+                               ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
+                               break;
+                       case SPACE_ACTION:
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_CHANNELS;
+                               ar->alignment= RGN_ALIGN_LEFT;
+                               ar->v2d.scroll= V2D_SCROLL_BOTTOM;
+                               ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+                               break;
+                       case SPACE_NLA:
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_CHANNELS;
+                               ar->alignment= RGN_ALIGN_LEFT;
+                               ar->v2d.scroll= V2D_SCROLL_BOTTOM;
+                               ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+                               break;
+                       case SPACE_NODE:
+                               ar= MEM_callocN(sizeof(ARegion), "nodetree area for node");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_CHANNELS;
+                               ar->alignment= RGN_ALIGN_LEFT;
+                               ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
+                               ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+                       case SPACE_FILE:
+                               /* channel (bookmarks/directories) region */
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_CHANNELS;
+                               ar->alignment= RGN_ALIGN_LEFT;
+                               ar->v2d.scroll= V2D_SCROLL_RIGHT;
+                               /* button UI region */
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_UI;
+                               ar->alignment= RGN_ALIGN_TOP;
+                               break;
+               }
+       }
+
+       /* main region */
+       ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+       
+       BLI_addtail(lb, ar);
+       ar->winrct= sa->totrct;
+       
+       ar->regiontype= RGN_TYPE_WINDOW;
+       
+       if(sl) {
+               /* if active spacetype has view2d data, copy that over to main region */
+               /* and we split view3d */
+               switch(sl->spacetype) {
+                       case SPACE_VIEW3D:
+                               view3d_split_250((View3D *)sl, lb);
+                               break;          
+                                               
+                       case SPACE_OOPS:
+                       {
+                               SpaceOops *soops= (SpaceOops *)sl;
+                               
+                               memcpy(&ar->v2d, &soops->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll &= ~V2D_SCROLL_LEFT;
+                               ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
+                               ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
+                               ar->v2d.keepzoom |= (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPASPECT);
+                               ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
+                               ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
+                               //ar->v2d.flag |= V2D_IS_INITIALISED;
+                               
+                               soops->type= SO_OUTLINER;
+                       }
+                               break;
+                       case SPACE_TIME:
+                       {
+                               SpaceTime *stime= (SpaceTime *)sl;
+                               memcpy(&ar->v2d, &stime->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+                               ar->v2d.align |= V2D_ALIGN_NO_NEG_Y;
+                               ar->v2d.keepofs |= V2D_LOCKOFS_Y;
+                               ar->v2d.keepzoom |= V2D_LOCKZOOM_Y;
+                               ar->v2d.tot.ymin= ar->v2d.cur.ymin= -10.0;
+                               ar->v2d.min[1]= ar->v2d.max[1]= 20.0;
+                       }
+                               break;
+                       case SPACE_IPO:
+                       {
+                               SpaceIpo *sipo= (SpaceIpo *)sl;
+                               memcpy(&ar->v2d, &sipo->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+                               ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
+                               //ar->v2d.flag |= V2D_IS_INITIALISED;
+                               break;
+                       }
+                       case SPACE_SOUND:
+                       {
+                               SpaceSound *ssound= (SpaceSound *)sl;
+                               memcpy(&ar->v2d, &ssound->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+                               ar->v2d.scroll |= (V2D_SCROLL_LEFT);
+                               //ar->v2d.flag |= V2D_IS_INITIALISED;
+                               break;
+                       }
+                       case SPACE_NLA:
+                       {
+                               SpaceNla *snla= (SpaceNla *)sl;
+                               memcpy(&ar->v2d, &snla->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+                               ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
+                               ar->v2d.align = V2D_ALIGN_NO_POS_Y;
+                               ar->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
+                               break;
+                       }
+                       case SPACE_ACTION:
+                       {
+                               /* we totally reinit the view for the Action Editor, as some old instances had some weird cruft set */
+                               ar->v2d.tot.xmin= -20.0f;
+                               ar->v2d.tot.ymin= (float)(-sa->winy);
+                               ar->v2d.tot.xmax= (float)(sa->winx);
+                               ar->v2d.tot.ymax= 0.0f;
+                               
+                               ar->v2d.cur= ar->v2d.tot;
+                               
+                               ar->v2d.min[0]= 0.0f;
+                               ar->v2d.min[1]= 0.0f;
+                               
+                               ar->v2d.max[0]= MAXFRAMEF;
+                               ar->v2d.max[1]= 10000.0f;
+                               
+                               ar->v2d.minzoom= 0.01f;
+                               ar->v2d.maxzoom= 50;
+                               ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+                               ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
+                               ar->v2d.keepzoom= V2D_LOCKZOOM_Y;
+                               ar->v2d.align= V2D_ALIGN_NO_POS_Y;
+                               ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
+                               break;
+                       }
+                       case SPACE_SEQ:
+                       {
+                               SpaceSeq *sseq= (SpaceSeq *)sl;
+                               memcpy(&ar->v2d, &sseq->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+                               ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
+                               ar->v2d.align= V2D_ALIGN_NO_NEG_Y;
+                               ar->v2d.flag |= V2D_IS_INITIALISED;
+                               break;
+                       }
+                       case SPACE_NODE:
+                       {
+                               SpaceNode *snode= (SpaceNode *)sl;
+                               memcpy(&ar->v2d, &snode->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
+                               ar->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+                               break;
+                       }
+                       case SPACE_BUTS:
+                       {
+                               SpaceButs *sbuts= (SpaceButs *)sl;
+                               memcpy(&ar->v2d, &sbuts->v2d, sizeof(View2D));
+                               ar->v2d.keepzoom |= V2D_KEEPASPECT;
+                               break;
+                       }
+                       case SPACE_FILE:
+                       {
+                               // SpaceFile *sfile= (SpaceFile *)sl;
+                               ar->v2d.tot.xmin = ar->v2d.tot.ymin = 0;
+                               ar->v2d.tot.xmax = ar->winx;
+                               ar->v2d.tot.ymax = ar->winy;
+                               ar->v2d.cur = ar->v2d.tot;
+                               ar->regiontype= RGN_TYPE_WINDOW;
+                               ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
+                               ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
+                               ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+                               break;
+                       }
+                               //case SPACE_XXX: // FIXME... add other ones
+                               //      memcpy(&ar->v2d, &((SpaceXxx *)sl)->v2d, sizeof(View2D));
+                               //      break;
+               }
+       }
+}
+
 static void do_versions_windowmanager_2_50(bScreen *screen)
 {
-       struct ScrArea *sa;
-       struct ARegion *ar;
+       ScrArea *sa;
+       SpaceLink *sl;
        
        /* add regions */
        for(sa= screen->areabase.first; sa; sa= sa->next) {
+               
                /* we keep headertype variable to convert old files only */
-               if(sa->headertype) {
-                       ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
-                       BLI_addtail(&sa->regionbase, ar);
-                       ar->regiontype= RGN_TYPE_HEADER;
-                       ar->minsize= HEADERY;   // DNA_screen_types.h
-                       if(sa->headertype==1)
-                               ar->alignment= RGN_ALIGN_BOTTOM;
-                       else
-                               ar->alignment= RGN_ALIGN_TOP;
-               }
+               if(sa->headertype)
+                       area_add_header_region(sa, &sa->regionbase);
+               
+               area_add_window_regions(sa, sa->spacedata.first, &sa->regionbase);
                
-               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
-               BLI_addtail(&sa->regionbase, ar);
-               ar->winrct= sa->totrct;
-               ar->regiontype= RGN_TYPE_WINDOW;
+               /* space imageselect is depricated */
+               for(sl= sa->spacedata.first; sl; sl= sl->next) {
+                       if(sl->spacetype==SPACE_IMASEL)
+                               sl->spacetype= SPACE_INFO;      /* spacedata then matches */
+               }               
+               
+               /* pushed back spaces also need regions! */
+               if(sa->spacedata.first) {
+                       sl= sa->spacedata.first;
+                       for(sl= sl->next; sl; sl= sl->next) {
+                               if(sa->headertype)
+                                       area_add_header_region(sa, &sl->regionbase);
+                               area_add_window_regions(sa, sl, &sl->regionbase);
+                       }
+               }
        }
 }
 
@@ -4902,7 +5952,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                while(ob) {
                        ob->mass= 1.0f;
                        ob->damping= 0.1f;
-                       ob->quat[1]= 1.0f;
+                       /*ob->quat[1]= 1.0f;*/ /* quats arnt used yet */
                        ob= ob->id.next;
                }
 
@@ -4913,7 +5963,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                while(sl) {
                                        if(sl->spacetype==SPACE_BUTS) {
                                                SpaceButs *sbuts= (SpaceButs*) sl;
-                                               //XXX sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK;
+                                               sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK;
                                        }
                                        sl= sl->next;
                                }
@@ -4972,7 +6022,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        while (act) {
                                if(act->type==ACT_IPO) {
                                        ia= act->data;
-                                       prop= get_property(ob, ia->name);
+                                       prop= get_ob_property(ob, ia->name);
                                        if(prop) {
                                                ia->type= ACT_IPO_FROM_PROP;
                                        }
@@ -5192,8 +6242,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                while (ob) {
                        prop= ob->prop.first;
                        while(prop) {
-                               if (prop->type == PROP_TIME) {
-                                       // convert old PROP_TIME values from int to float
+                               if (prop->type == GPROP_TIME) {
+                                       // convert old GPROP_TIME values from int to float
                                        *((float *)&prop->data) = (float) prop->data;
                                }
 
@@ -5561,52 +6611,52 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        if (sl->spacetype==SPACE_BUTS) {
                                                SpaceButs *sbuts= (SpaceButs *) sl;
 
-//XXX                                          sbuts->v2d.maxzoom= 1.2f;
-//XXX                                          sbuts->align= 1;        /* horizontal default */
-//XXX                                          
-//XXX                                          if(sbuts->mainb==BUTS_LAMP) {
-//XXX                                                  sbuts->mainb= CONTEXT_SHADING;
-//XXX                                                  sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_MAT) {
-//XXX                                                  sbuts->mainb= CONTEXT_SHADING;
-//XXX                                                  sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_TEX) {
-//XXX                                                  sbuts->mainb= CONTEXT_SHADING;
-//XXX                                                  sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_TEX;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_ANIM) {
-//XXX                                                  sbuts->mainb= CONTEXT_OBJECT;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_WORLD) {
-//XXX                                                  sbuts->mainb= CONTEXT_SCENE;
-//XXX                                                  sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_WORLD;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_RENDER) {
-//XXX                                                  sbuts->mainb= CONTEXT_SCENE;
-//XXX                                                  sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_RENDER;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_GAME) {
-//XXX                                                  sbuts->mainb= CONTEXT_LOGIC;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_FPAINT) {
-//XXX                                                  sbuts->mainb= CONTEXT_EDITING;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_RADIO) {
-//XXX                                                  sbuts->mainb= CONTEXT_SHADING;
-//XXX                                                  sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_RAD;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_CONSTRAINT) {
-//XXX                                                  sbuts->mainb= CONTEXT_OBJECT;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_SCRIPT) {
-//XXX                                                  sbuts->mainb= CONTEXT_OBJECT;
-//XXX                                          }
-//XXX                                          else if(sbuts->mainb==BUTS_EDIT) {
-//XXX                                                  sbuts->mainb= CONTEXT_EDITING;
-//XXX                                          }
-//XXX                                          else sbuts->mainb= CONTEXT_SCENE;
+                                               sbuts->v2d.maxzoom= 1.2f;
+                                               sbuts->align= 1;        /* horizontal default */
+                                       
+                                               if(sbuts->mainb==BUTS_LAMP) {
+                                                       sbuts->mainb= CONTEXT_SHADING;
+                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
+                                               }
+                                               else if(sbuts->mainb==BUTS_MAT) {
+                                                       sbuts->mainb= CONTEXT_SHADING;
+                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
+                                               }
+                                               else if(sbuts->mainb==BUTS_TEX) {
+                                                       sbuts->mainb= CONTEXT_SHADING;
+                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_TEX;
+                                               }
+                                               else if(sbuts->mainb==BUTS_ANIM) {
+                                                       sbuts->mainb= CONTEXT_OBJECT;
+                                               }
+                                               else if(sbuts->mainb==BUTS_WORLD) {
+                                                       sbuts->mainb= CONTEXT_SCENE;
+                                                       sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_WORLD;
+                                               }
+                                               else if(sbuts->mainb==BUTS_RENDER) {
+                                                       sbuts->mainb= CONTEXT_SCENE;
+                                                       sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_RENDER;
+                                               }
+                                               else if(sbuts->mainb==BUTS_GAME) {
+                                                       sbuts->mainb= CONTEXT_LOGIC;
+                                               }
+                                               else if(sbuts->mainb==BUTS_FPAINT) {
+                                                       sbuts->mainb= CONTEXT_EDITING;
+                                               }
+                                               else if(sbuts->mainb==BUTS_RADIO) {
+                                                       sbuts->mainb= CONTEXT_SHADING;
+                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_RAD;
+                                               }
+                                               else if(sbuts->mainb==BUTS_CONSTRAINT) {
+                                                       sbuts->mainb= CONTEXT_OBJECT;
+                                               }
+                                               else if(sbuts->mainb==BUTS_SCRIPT) {
+                                                       sbuts->mainb= CONTEXT_OBJECT;
+                                               }
+                                               else if(sbuts->mainb==BUTS_EDIT) {
+                                                       sbuts->mainb= CONTEXT_EDITING;
+                                               }
+                                               else sbuts->mainb= CONTEXT_SCENE;
                                        }
                                }
                        }
@@ -5876,10 +6926,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                while(sce) {
                        ed= sce->ed;
                        if(ed) {
-                               WHILE_SEQ(&ed->seqbase) { //XXX todo replace WHILE_SEQ
-                                       if(seq->type==SEQ_IMAGE || seq->type==SEQ_MOVIE) seq->flag |= SEQ_MAKE_PREMUL;
+                               SEQ_BEGIN(sce->ed, seq) {
+                                       if(seq->type==SEQ_IMAGE || seq->type==SEQ_MOVIE)
+                                               seq->flag |= SEQ_MAKE_PREMUL;
                                }
-                               END_SEQ
+                               SEQ_END
                        }
                        
                        sce= sce->id.next;
@@ -6276,7 +7327,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                sce->toolsettings->uvcalc_cubesize = 1.0f;
                                sce->toolsettings->uvcalc_mapdir = 1;
                                sce->toolsettings->uvcalc_mapalign = 1;
-                               sce->toolsettings->uvcalc_flag = 1;
+                               sce->toolsettings->uvcalc_flag = UVCALC_FILLHOLES;
                                sce->toolsettings->unwrapper = 1;
                        }
 
@@ -6603,7 +7654,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Material *ma;
                
                for(; cam; cam= cam->id.next) {
-                       cam->angle= 360.0f * atan(16.0f/cam->lens) / M_PI;
+                       cam->angle= 360.0f * (float)atan(16.0f/cam->lens) / (float)M_PI;
                }
 
                for(ma=main->mat.first; ma; ma= ma->id.next) {
@@ -6728,7 +7779,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                else
                                        la->ray_samp_method = LA_SAMP_HALTON;
                                
-                               la->adapt_thresh = 0.001;
+                               la->adapt_thresh = 0.001f;
                        }
                }
        }
@@ -6740,7 +7791,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Lamp *la;
                Material *ma;
                ParticleSettings *part;
+               World *wrld;
                Mesh *me;
+               bNodeTree *ntree;
+               Tex *tex;
+               ModifierData *md;
+               ParticleSystem *psys;
                
                /* unless the file was created 2.44.3 but not 2.45, update the constraints */
                if ( !(main->versionfile==244 && main->subversionfile==3) &&
@@ -6770,14 +7826,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                                        curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
                                                        }
                                                                break;
-                                                       case CONSTRAINT_TYPE_STRETCHTO:
-                                                       {
-                                                               bStretchToConstraint *data= (bStretchToConstraint *)curcon->data;
-                                                               
-                                                               /* force recalc of rest-length */
-                                                               data->orglength = 0;
-                                                       }
-                                                               break;
                                                }       
                                        }
                                }
@@ -6809,14 +7857,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                                                        curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
                                                                        }                                                       
                                                                                break;
-                                                                       case CONSTRAINT_TYPE_STRETCHTO:
-                                                                       {
-                                                                               bStretchToConstraint *data= (bStretchToConstraint *)curcon->data;
-                                                                               
-                                                                               /* force recalc of rest-length */
-                                                                               data->orglength = 0;
-                                                                       }
-                                                                               break;
                                                                }
                                                        }
                                                        
@@ -6846,14 +7886,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                                if(sl->spacetype==SPACE_IMASEL) {
                                                        SpaceImaSel *simasel= (SpaceImaSel*) sl;
-                                                       simasel->blockscale= 0.7;
+                                                       simasel->blockscale= 0.7f;
                                                        /* view 2D */
-                                                       simasel->v2d.tot.xmin=  -10.0;
-                                                       simasel->v2d.tot.ymin=  -10.0;
+                                                       simasel->v2d.tot.xmin=  -10.0f;
+                                                       simasel->v2d.tot.ymin=  -10.0f;
                                                        simasel->v2d.tot.xmax= (float)sa->winx + 10.0f;
                                                        simasel->v2d.tot.ymax= (float)sa->winy + 10.0f;                                         
-                                                       simasel->v2d.cur.xmin=  0.0;
-                                                       simasel->v2d.cur.ymin=  0.0;
+                                                       simasel->v2d.cur.xmin=  0.0f;
+                                                       simasel->v2d.cur.ymin=  0.0f;
                                                        simasel->v2d.cur.xmax= (float)sa->winx;
                                                        simasel->v2d.cur.ymax= (float)sa->winy;                                         
                                                        simasel->v2d.min[0]= 1.0;
@@ -6863,8 +7903,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                        simasel->v2d.minzoom= 0.5f;
                                                        simasel->v2d.maxzoom= 1.21f;                                            
                                                        simasel->v2d.scroll= 0;
-                                                       simasel->v2d.keepaspect= 1;
-                                                       simasel->v2d.keepzoom= 1;
+                                                       simasel->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
                                                        simasel->v2d.keeptot= 0;
                                                        simasel->prv_h = 96;
                                                        simasel->prv_w = 96;
@@ -6881,6 +7920,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
 
+               /* add point caches */
+               for(ob=main->object.first; ob; ob=ob->id.next) {
+                       if(ob->soft && !ob->soft->pointcache)
+                               ob->soft->pointcache= BKE_ptcache_add();
+
+                       for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+                               if(psys->soft && !psys->soft->pointcache)
+                                       psys->soft->pointcache= BKE_ptcache_add();
+                               if(!psys->pointcache)
+                                       psys->pointcache= BKE_ptcache_add();
+                       }
+
+                       for(md=ob->modifiers.first; md; md=md->next) {
+                               if(md->type==eModifierType_Cloth) {
+                                       ClothModifierData *clmd = (ClothModifierData*) md;
+                                       if(!clmd->point_cache)
+                                               clmd->point_cache= BKE_ptcache_add();
+                               }
+                       }
+               }
+
                /* Copy over old per-level multires vertex data
                   into a single vertex array in struct Multires */
                for(me = main->mesh.first; me; me=me->id.next) {
@@ -6912,11 +7972,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                
                for(ma=main->mat.first; ma; ma= ma->id.next) {
                        if(ma->samp_gloss_mir == 0) {
-                               ma->gloss_mir = ma->gloss_tra= 1.0;
-                               ma->aniso_gloss_mir = 1.0;
+                               ma->gloss_mir = ma->gloss_tra= 1.0f;
+                               ma->aniso_gloss_mir = 1.0f;
                                ma->samp_gloss_mir = ma->samp_gloss_tra= 18;
-                               ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005;
-                               ma->dist_mir = 0.0;
+                               ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005f;
+                               ma->dist_mir = 0.0f;
                                ma->fadeto_mir = MA_RAYMIR_FADETOSKY;
                        }
 
@@ -6936,6 +7996,54 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
 
+               for(wrld=main->world.first; wrld; wrld= wrld->id.next) {
+                       if(wrld->ao_approx_error == 0.0f)
+                               wrld->ao_approx_error= 0.25f;
+               }
+
+               for(sce= main->scene.first; sce; sce= sce->id.next) {
+                       if(sce->nodetree)
+                               ntree_version_245(fd, lib, sce->nodetree);
+
+                       if(sce->r.simplify_shadowsamples == 0) {
+                               sce->r.simplify_subsurf= 6;
+                               sce->r.simplify_particles= 1.0f;
+                               sce->r.simplify_shadowsamples= 16;
+                               sce->r.simplify_aosss= 1.0f;
+                       }
+
+                       if(sce->r.cineongamma == 0) {
+                               sce->r.cineonblack= 95;
+                               sce->r.cineonwhite= 685;
+                               sce->r.cineongamma= 1.7f;
+                       }
+               }
+
+               for(ntree=main->nodetree.first; ntree; ntree= ntree->id.next)
+                       ntree_version_245(fd, lib, ntree);
+
+               /* fix for temporary flag changes during 245 cycle */
+               for(ima= main->image.first; ima; ima= ima->id.next) {
+                       if(ima->flag & IMA_OLD_PREMUL) {
+                               ima->flag &= ~IMA_OLD_PREMUL;
+                               ima->flag |= IMA_DO_PREMUL;
+                       }
+               }
+
+               for(tex=main->tex.first; tex; tex=tex->id.next) {
+                       if(tex->iuser.flag & IMA_OLD_PREMUL) {
+                               tex->iuser.flag &= ~IMA_OLD_PREMUL;
+                               tex->iuser.flag |= IMA_DO_PREMUL;
+
+                       }
+
+                       ima= newlibadr(fd, lib, tex->ima);
+                       if(ima && (tex->iuser.flag & IMA_DO_PREMUL)) { 
+                               ima->flag &= ~IMA_OLD_PREMUL;
+                               ima->flag |= IMA_DO_PREMUL;
+                       }
+               }
+
                if (main->versionfile < 245 || main->subversionfile < 12)
                {
                        /* initialize skeleton generation toolsettings */
@@ -6958,6 +8066,24 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
        }
+       
+       /* sanity check for skgen
+        * */
+       {
+               Scene *sce;
+               for(sce=main->scene.first; sce; sce = sce->id.next)
+               {
+                       if (sce->toolsettings->skgen_subdivisions[0] == sce->toolsettings->skgen_subdivisions[1] ||
+                               sce->toolsettings->skgen_subdivisions[0] == sce->toolsettings->skgen_subdivisions[2] ||
+                               sce->toolsettings->skgen_subdivisions[1] == sce->toolsettings->skgen_subdivisions[2])
+                       {
+                                       sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
+                                       sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
+                                       sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
+                       }
+               }
+       }
+       
 
        if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 2)) {
                Image *ima;
@@ -6989,9 +8115,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                /* foreground color needs to be somthing other then black */
                Scene *sce;
                for(sce= main->scene.first; sce; sce=sce->id.next) {
-                       sce->r.fg_stamp[0] = sce->r.fg_stamp[1] = sce->r.fg_stamp[2] = 0.8;
-                       sce->r.fg_stamp[3] = 1.0; /* dont use text alpha yet */
-                       sce->r.bg_stamp[3] = 0.25; /* make sure the background has full alpha */
+                       sce->r.fg_stamp[0] = sce->r.fg_stamp[1] = sce->r.fg_stamp[2] = 0.8f;
+                       sce->r.fg_stamp[3] = 1.0f; /* dont use text alpha yet */
+                       sce->r.bg_stamp[3] = 0.25f; /* make sure the background has full alpha */
                }
        }
 
@@ -7086,71 +8212,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                sb->keys = NULL;
                                sb->totkey = 0;
-                               ob->softflag &= ~OB_SB_BAKESET;
                        }
                }
        }
 
-       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 7)) {
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
+               Scene *sce;
                Object *ob;
-               bPoseChannel *pchan;
-               bConstraint *con;
-               bConstraintTarget *ct;
-               
-               for(ob = main->object.first; ob; ob= ob->id.next) {
-                       if(ob->pose) {
-                               for(pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
-                                       for(con=pchan->constraints.first; con; con=con->next) {
-                                               if(con->type==CONSTRAINT_TYPE_PYTHON) {
-                                                       bPythonConstraint *data= (bPythonConstraint *)con->data;
-                                                       if (data->tar) {
-                                                               /* version patching needs to be done */
-                                                               ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
-                                                               
-                                                               ct->tar = data->tar;
-                                                               strcpy(ct->subtarget, data->subtarget);
-                                                               ct->space = con->tarspace;
-                                                               
-                                                               BLI_addtail(&data->targets, ct);
-                                                               data->tarnum++;
-                                                               
-                                                               /* clear old targets to avoid problems */
-                                                               data->tar = NULL;
-                                                               strcpy(data->subtarget, "");
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       for(con=ob->constraints.first; con; con=con->next) {
-                               if(con->type==CONSTRAINT_TYPE_PYTHON) {
-                                       bPythonConstraint *data= (bPythonConstraint *)con->data;
-                                       if (data->tar) {
-                                               /* version patching needs to be done */
-                                               ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
-                                               
-                                               ct->tar = data->tar;
-                                               strcpy(ct->subtarget, data->subtarget);
-                                               ct->space = con->tarspace;
-                                               
-                                               BLI_addtail(&data->targets, ct);
-                                               data->tarnum++;
-                                               
-                                               /* clear old targets to avoid problems */
-                                               data->tar = NULL;
-                                               strcpy(data->subtarget, "");
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
-               Scene *sce;
-               Object *ob;
-               PartEff *paf=0;
-
+               PartEff *paf=0;
+
                for(ob = main->object.first; ob; ob= ob->id.next) {
                        if(ob->soft && ob->soft->keys) {
                                SoftBody *sb = ob->soft;
@@ -7165,7 +8235,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                sb->keys = NULL;
                                sb->totkey = 0;
-                               ob->softflag &= ~OB_SB_BAKESET;
                        }
 
                        /* convert old particles to new system */
@@ -7177,17 +8246,19 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                /* create new particle system */
                                psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+                               psys->pointcache = BKE_ptcache_add();
 
                                part = psys->part = psys_new_settings("PSys", main);
                                
                                /* needed for proper libdata lookup */
                                oldnewmap_insert(fd->libmap, psys->part, psys->part, 0);
+                               part->id.lib= ob->id.lib;
 
                                part->id.us--;
                                part->id.flag |= (ob->id.flag & LIB_NEEDLINK);
                                
                                psys->totpart=0;
-                               psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+                               psys->flag= PSYS_ENABLED|PSYS_CURRENT;
 
                                BLI_addtail(&ob->particlesystem, psys);
 
@@ -7211,6 +8282,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                part->eff_group = paf->group;
 
+                               /* old system didn't interpolate between keypoints at render time */
+                               part->draw_step = part->ren_step = 0;
+
                                /* physics */
                                part->normfac = paf->normfac * 25.0f;
                                part->obfac = paf->obfac;
@@ -7263,10 +8337,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                        ob->transflag &= ~OB_DUPLIVERTS;
 
                                                        part->draw_as = PART_DRAW_OB;
+
+                                                       /* needed for proper libdata lookup */
+                                                       oldnewmap_insert(fd->libmap, dup, dup, 0);
                                                }
                                        }
                                }
 
+                               
+                               {
+                                       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+                                       if(fluidmd && fluidmd->fss && fluidmd->fss->type == OB_FLUIDSIM_PARTICLE)
+                                               part->type = PART_FLUID;
+                               }
+
                                free_effects(&ob->effect);
 
                                printf("Old particle system converted to new system.\n");
@@ -7334,17 +8418,405 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                strip->scale = length / (repeat * actlength);
                                if (strip->scale == 0.0f) strip->scale= 1.0f;
                        }       
+                       if(ob->soft){
+                               ob->soft->inpush =  ob->soft->inspring;
+                               ob->soft->shearstiff = 1.0f; 
+                       }
+               }
+       }
+
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 14)) {
+               Scene *sce;
+               Sequence *seq;
+               
+               for(sce=main->scene.first; sce; sce=sce->id.next) {
+                       SEQ_BEGIN(sce->ed, seq) {
+                               if (seq->blend_mode == 0)
+                                       seq->blend_opacity = 100.0f;
+                       }
+                       SEQ_END
+               }
+       }
+       
+       /*fix broken group lengths in id properties*/
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 15)) {
+               idproperties_fix_group_lengths(main->scene);
+               idproperties_fix_group_lengths(main->library);
+               idproperties_fix_group_lengths(main->object);
+               idproperties_fix_group_lengths(main->mesh);
+               idproperties_fix_group_lengths(main->curve);
+               idproperties_fix_group_lengths(main->mball);
+               idproperties_fix_group_lengths(main->mat);
+               idproperties_fix_group_lengths(main->tex);
+               idproperties_fix_group_lengths(main->image);
+               idproperties_fix_group_lengths(main->wave);
+               idproperties_fix_group_lengths(main->latt);
+               idproperties_fix_group_lengths(main->lamp);
+               idproperties_fix_group_lengths(main->camera);
+               idproperties_fix_group_lengths(main->ipo);
+               idproperties_fix_group_lengths(main->key);
+               idproperties_fix_group_lengths(main->world);
+               idproperties_fix_group_lengths(main->screen);
+               idproperties_fix_group_lengths(main->script);
+               idproperties_fix_group_lengths(main->vfont);
+               idproperties_fix_group_lengths(main->text);
+               idproperties_fix_group_lengths(main->sound);
+               idproperties_fix_group_lengths(main->group);
+               idproperties_fix_group_lengths(main->armature);
+               idproperties_fix_group_lengths(main->action);
+               idproperties_fix_group_lengths(main->nodetree);
+               idproperties_fix_group_lengths(main->brush);
+               idproperties_fix_group_lengths(main->particle);         
+       }
+
+       /* sun/sky */
+       if(main->versionfile < 246) {
+               Object *ob;
+               bActuator *act;
+
+               /* dRot actuator change direction in 2.46 */
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       for(act= ob->actuators.first; act; act= act->next) {
+                               if (act->type == ACT_OBJECT) {
+                                       bObjectActuator *ba= act->data;
+
+                                       ba->drot[0] = -ba->drot[0];
+                                       ba->drot[1] = -ba->drot[1];
+                                       ba->drot[2] = -ba->drot[2];
+                               }
+                       }
+               }
+       }
+       
+       // convert fluids to modifier
+       if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1))
+       {
+               Object *ob;
+               
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       if(ob->fluidsimSettings)
+                       {
+                               FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifier_new(eModifierType_Fluidsim);
+                               BLI_addhead(&ob->modifiers, (ModifierData *)fluidmd);
+                               
+                               MEM_freeN(fluidmd->fss);
+                               fluidmd->fss = MEM_dupallocN(ob->fluidsimSettings);
+                               fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
+                               MEM_freeN(ob->fluidsimSettings);
+                               
+                               fluidmd->fss->lastgoodframe = INT_MAX;
+                               fluidmd->fss->flag = 0;
+                       }
+               }
+       }
+       
+
+       if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
+               Mesh *me;
+
+               for(me=main->mesh.first; me; me= me->id.next)
+                       alphasort_version_246(fd, lib, me);
+       }
+       
+       if(main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)){
+               Object *ob;
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       if(ob->pd && (ob->pd->forcefield == PFIELD_WIND))
+                               ob->pd->f_noise = 0.0f;
+               }
+       }
+
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 2)){
+               Object *ob;
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       ob->gameflag |= OB_COLLISION;
+                       ob->margin = 0.06f;
+               }
+       }
+
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 3)){
+               Object *ob;
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       // Starting from subversion 3, ACTOR is a separate feature.
+                       // Before it was conditioning all the other dynamic flags
+                       if (!(ob->gameflag & OB_ACTOR))
+                               ob->gameflag &= ~(OB_GHOST|OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_COLLISION_RESPONSE);
+                       /* suitable default for older files */
+               }
+       }
+
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 4)){
+               Scene *sce= main->scene.first;
+               while(sce) {
+                       if(sce->frame_step==0)
+                               sce->frame_step= 1;
+                       sce= sce->id.next;
+               }
+       }
+
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 5)) {
+               Lamp *la= main->lamp.first;
+               for(; la; la= la->id.next) {
+                       la->skyblendtype= MA_RAMP_ADD;
+                       la->skyblendfac= 1.0f;
                }
        }
+       
+       /* set the curve radius interpolation to 2.47 default - easy */
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 6)) {
+               Curve *cu;
+               Nurb *nu;
                
+               for(cu= main->curve.first; cu; cu= cu->id.next) {
+                       for(nu= cu->nurb.first; nu; nu= nu->next) {
+                               if (nu) {
+                                       nu->radius_interp = 3;
+                                       
+                                       /* resolu and resolv are now used differently for surfaces
+                                        * rather then using the resolution to define the entire number of divisions,
+                                        * use it for the number of divisions per segment
+                                        */
+                                       if (nu->pntsv > 1) {
+                                               nu->resolu = MAX2( 1, (int)(((float)nu->resolu / (float)nu->pntsu)+0.5f) );
+                                               nu->resolv = MAX2( 1, (int)(((float)nu->resolv / (float)nu->pntsv)+0.5f) );
+                                       }
+                               }
+                       }
+               }
+       }
+       /* direction constraint actuators were always local in previous version */
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 7)) {
+               bActuator *act;
+               Object *ob;
                
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       for(act= ob->actuators.first; act; act= act->next) {
+                               if (act->type == ACT_CONSTRAINT) {
+                                       bConstraintActuator *coa = act->data;
+                                       if (coa->type == ACT_CONST_TYPE_DIST) {
+                                               coa->flag |= ACT_CONST_LOCAL;
+                                       }
+                               }
+                       }
+               }
+       }
+       /* autokey mode settings now used from scene, but need to be initialised off userprefs */
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 8)) {
+               Scene *sce;
+               
+               for (sce= main->scene.first; sce; sce= sce->id.next) {
+                       if (sce->autokey_mode == 0)
+                               sce->autokey_mode= U.autokey_mode;
+               }
+       }
+
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 9)) {
+               Lamp *la= main->lamp.first;
+               for(; la; la= la->id.next) {
+                       la->sky_exposure= 1.0f;
+               }
+       }
+       
+       /* BGE message actuators needed OB prefix, very confusing */
+       if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 10)) {
+               bActuator *act;
+               Object *ob;
+               
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       for(act= ob->actuators.first; act; act= act->next) {
+                               if (act->type == ACT_MESSAGE) {
+                                       bMessageActuator *msgAct = (bMessageActuator *) act->data;
+                                       if (strlen(msgAct->toPropName) > 2) {
+                                               /* strip first 2 chars, would have only worked if these were OB anyway */
+                                               memmove( msgAct->toPropName, msgAct->toPropName+2, sizeof(msgAct->toPropName)-2 );
+                                       } else {
+                                               msgAct->toPropName[0] = '\0';
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (main->versionfile < 248) {
+               Lamp *la;
+
+               for(la=main->lamp.first; la; la= la->id.next) {
+                       if(la->atm_turbidity == 0.0) {
+                               la->sun_effect_type = 0;
+                               la->horizon_brightness = 1.0f;
+                               la->spread = 1.0f;
+                               la->sun_brightness = 1.0f;
+                               la->sun_size = 1.0f;
+                               la->backscattered_light = 1.0f;
+                               la->atm_turbidity = 2.0f;
+                               la->atm_inscattering_factor = 1.0f;
+                               la->atm_extinction_factor = 1.0f;
+                               la->atm_distance_factor = 1.0f;
+                               la->sun_intensity = 1.0f;
+                       }
+               }
+       }
+
+       if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) {
+               Scene *sce;
+               
+               /* Note, these will need to be added for painting */
+               for (sce= main->scene.first; sce; sce= sce->id.next) {
+                       sce->toolsettings->imapaint.seam_bleed = 2;
+                       sce->toolsettings->imapaint.normal_angle = 80;
+               }
+       }
+       if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) {
+               bScreen *sc;
+               
+               /* adjust default settings for Animation Editors */
+               for (sc= main->screen.first; sc; sc= sc->id.next) {
+                       ScrArea *sa;
+                       
+                       for (sa= sc->areabase.first; sa; sa= sa->next) { 
+                               SpaceLink *sl;
+                               
+                               for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                                       switch (sl->spacetype) {
+                                               case SPACE_ACTION:
+                                               {
+                                                       SpaceAction *sact= (SpaceAction *)sl;
+                                                       
+                                                       sact->mode= SACTCONT_DOPESHEET;
+                                                       sact->autosnap= SACTSNAP_FRAME;
+                                               }
+                                                       break;
+                                               case SPACE_IPO:
+                                               {
+                                                       SpaceIpo *sipo= (SpaceIpo *)sl;
+                                                       sipo->autosnap= SACTSNAP_FRAME;
+                                               }
+                                                       break;
+                                               case SPACE_NLA:
+                                               {
+                                                       SpaceNla *snla= (SpaceNla *)sl;
+                                                       snla->autosnap= SACTSNAP_FRAME;
+                                               }
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+       }
+
        if (main->versionfile < 250) {
                bScreen *screen;
+               Scene *scene;
+               Material *ma;
+               Scene *sce;
+               Tex *tx;
                
                for(screen= main->screen.first; screen; screen= screen->id.next)
                        do_versions_windowmanager_2_50(screen);
-       }
                
+               /* old Animation System (using IPO's) needs to be converted to the new Animato system 
+                * (NOTE: conversion code in blenkernel/intern/ipo.c for now)
+                */
+               //do_versions_ipos_to_animato(main);
+               
+               /* struct audio data moved to renderdata */
+               for(scene= main->scene.first; scene; scene= scene->id.next) {
+                       scene->r.audio = scene->audio;
+                       
+                       if(!scene->toolsettings->uv_selectmode)
+                               scene->toolsettings->uv_selectmode= UV_SELECT_VERTEX;
+               }
+               
+               /* shader, composit and texture node trees have id.name empty, put something in
+                * to have them show in RNA viewer and accessible otherwise.
+                */
+               for(ma= main->mat.first; ma; ma= ma->id.next) {
+                       if(ma->nodetree && strlen(ma->nodetree->id.name)==0)
+                               strcpy(ma->nodetree->id.name, "NTShader Nodetree");
+               }
+               /* and composit trees */
+               for(sce= main->scene.first; sce; sce= sce->id.next) {
+                       if(sce->nodetree && strlen(sce->nodetree->id.name)==0)
+                               strcpy(sce->nodetree->id.name, "NTComposit Nodetree");
+               }
+               /* and texture trees */
+               for(tx= main->tex.first; tx; tx= tx->id.next) {
+                       if(tx->nodetree && strlen(tx->nodetree->id.name)==0)
+                               strcpy(tx->nodetree->id.name, "NTTexture Nodetree");
+               }
+       }
+
+       /* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can
+          bump the version (or sub-version.) */
+       {
+               Object *ob;
+               int i;
+
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+
+                       if(ob->type == OB_MESH) {
+                               Mesh *me = newlibadr(fd, lib, ob->data);
+                               void *olddata = ob->data;
+                               ob->data = me;
+
+                               if(me && me->mr) {
+                                       MultiresLevel *lvl;
+                                       ModifierData *md;
+                                       MultiresModifierData *mmd;
+                                       DerivedMesh *dm, *orig;
+
+                                       /* Load original level into the mesh */
+                                       lvl = me->mr->levels.first;
+                                       CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert);
+                                       CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge);
+                                       CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface);
+                                       me->totvert = lvl->totvert;
+                                       me->totedge = lvl->totedge;
+                                       me->totface = lvl->totface;
+                                       me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
+                                       me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
+                                       me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
+                                       memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert);
+                                       for(i = 0; i < me->totedge; ++i) {
+                                               me->medge[i].v1 = lvl->edges[i].v[0];
+                                               me->medge[i].v2 = lvl->edges[i].v[1];
+                                       }
+                                       for(i = 0; i < me->totface; ++i) {
+                                               me->mface[i].v1 = lvl->faces[i].v[0];
+                                               me->mface[i].v2 = lvl->faces[i].v[1];
+                                               me->mface[i].v3 = lvl->faces[i].v[2];
+                                               me->mface[i].v4 = lvl->faces[i].v[3];
+                                       }
+
+                                       /* Add a multires modifier to the object */
+                                       md = ob->modifiers.first;
+                                       while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
+                                               md = md->next;                          
+                                       mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires);
+                                       BLI_insertlinkbefore(&ob->modifiers, md, mmd);
+
+                                       multiresModifier_subdivide(mmd, ob, me->mr->level_count - 1, 1, 0);
+
+                                       mmd->lvl = mmd->totlvl;
+                                       orig = CDDM_from_mesh(me, NULL);
+                                       dm = multires_dm_create_from_derived(mmd, orig, me, 0, 0);
+                                       
+                                       multires_load_old(dm, me->mr);
+
+                                       *MultiresDM_get_flags(dm) |= MULTIRES_DM_UPDATE_ALWAYS;
+                                       dm->release(dm);
+                                       orig->release(orig);
+
+                                       /* Remove the old multires */
+                                       multires_free(me->mr);
+                                       me->mr = NULL;
+                               }
+
+                               ob->data = olddata;
+                       }
+               }
+       }
+                                      
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
@@ -7364,7 +8836,7 @@ static void lib_link_all(FileData *fd, Main *main)
        lib_link_material(fd, main);
        lib_link_texture(fd, main);
        lib_link_image(fd, main);
-       lib_link_ipo(fd, main);
+       lib_link_ipo(fd, main);         // XXX depreceated... still needs to be maintained for version patches still
        lib_link_key(fd, main);
        lib_link_world(fd, main);
        lib_link_lamp(fd, main);
@@ -7406,11 +8878,10 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
        return bhead;
 }
 
-BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
+BlendFileData *blo_read_file_internal(FileData *fd)
 {
        BHead *bhead= blo_firstbhead(fd);
        BlendFileData *bfd;
-       FileGlobal *fg = (FileGlobal *)NULL;
 
        bfd= MEM_callocN(sizeof(BlendFileData), "blendfiledata");
        bfd->main= MEM_callocN(sizeof(Main), "main");
@@ -7447,6 +8918,10 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
                        bhead = read_libblock(fd, fd->mainlist.last, bhead, LIB_READ+LIB_EXTERN, NULL);
                        break;
                        
+                       /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
+               case ID_SCRN:
+                       bhead->code= ID_SCR;
+                       /* deliberate pass on to default */
                default:
                        bhead = read_libblock(fd, bfd->main, bhead, LIB_LOCAL, NULL);
                }
@@ -7455,13 +8930,14 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
        /* do before read_libraries, but skip undo case */
 //     if(fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton)
                do_versions(fd, NULL, bfd->main);
-       
+
        read_libraries(fd, &fd->mainlist);
        
        blo_join_main(&fd->mainlist);
 
        lib_link_all(fd, bfd->main);
-       lib_verify_nodetree(bfd->main);
+       lib_verify_nodetree(bfd->main, 1);
+       fix_relpaths_library(fd->filename, bfd->main); /* make all relative paths, relative to the open blend file */
        
        link_global(fd, bfd);   /* as last */
        
@@ -7470,6 +8946,43 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
 
 /* ************* APPEND LIBRARY ************** */
 
+struct bheadsort {
+       BHead *bhead;
+       void *old;
+};
+
+static int verg_bheadsort(const void *v1, const void *v2)
+{
+       const struct bheadsort *x1=v1, *x2=v2;
+       
+       if( x1->old > x2->old) return 1;
+       else if( x1->old < x2->old) return -1;
+       return 0;
+}
+
+static void sort_bhead_old_map(FileData *fd)
+{
+       BHead *bhead;
+       struct bheadsort *bhs;
+       int tot= 0;
+       
+       for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead))
+               tot++;
+       
+       fd->tot_bheadmap= tot;
+       if(tot==0) return;
+       
+       bhs= fd->bheadmap= MEM_mallocN(tot*sizeof(struct bheadsort), "bheadsort");
+       
+       for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead), bhs++) {
+               bhs->bhead= bhead;
+               bhs->old= bhead->old;
+       }
+       
+       qsort(fd->bheadmap, tot, sizeof(struct bheadsort), verg_bheadsort);
+               
+}
+
 static BHead *find_previous_lib(FileData *fd, BHead *bhead)
 {
        for (; bhead; bhead= blo_prevbhead(fd, bhead))
@@ -7481,14 +8994,28 @@ static BHead *find_previous_lib(FileData *fd, BHead *bhead)
 
 static BHead *find_bhead(FileData *fd, void *old)
 {
+#if 0
        BHead *bhead;
-
+#endif
+       struct bheadsort *bhs, bhs_s;
+       
        if (!old)
                return NULL;
 
+       if (fd->bheadmap==NULL)
+               sort_bhead_old_map(fd);
+       
+       bhs_s.old= old;
+       bhs= bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct bheadsort), verg_bheadsort);
+
+       if(bhs)
+               return bhs->bhead;
+       
+#if 0
        for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead))
                if (bhead->old==old)
                        return bhead;
+#endif
 
        return NULL;
 }
@@ -7541,7 +9068,13 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
                                        ptr->curlib->parent= mainvar->curlib;
                                }
                                else {
-                                       //oldnewmap_insert(fd->libmap, bhead->old, id, 1);
+                                       /* The line below was commented by Ton (I assume), when Hos did the merge from the orange branch. rev 6568
+                                        * This line is NEEDED, the case is that you have 3 blend files...
+                                        * user.blend, lib.blend and lib_indirect.blend - if user.blend alredy references a "tree" from
+                                        * lib_indirect.blend but lib.blend does too, linking in a Scene or Group from lib.blend can result in an
+                                        * empty without the dupli group referenced. Once you save and reload the group would appier. - Campbell */
+                                       /* This crashes files, must look further into it */
+                                       /*oldnewmap_insert(fd->libmap, bhead->old, id, 1);*/
                                        
                                        change_idid_adr_fd(fd, bhead->old, id);
                                        if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name);
@@ -7565,6 +9098,9 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
        }
 }
 
+
+
+// XXX depreceated - old animation system
 static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
 {
        IpoCurve *icu;
@@ -7574,6 +9110,50 @@ static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
        }
 }
 
+// XXX depreceated - old animation system
+static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *chanbase)
+{
+       bConstraintChannel *chan;
+       for (chan=chanbase->first; chan; chan=chan->next) {
+               expand_doit(fd, mainvar, chan->ipo);
+       }
+}
+
+// XXX depreceated - old animation system
+static void expand_action(FileData *fd, Main *mainvar, bAction *act)
+{
+       bActionChannel *chan;
+       
+       for (chan=act->chanbase.first; chan; chan=chan->next) {
+               expand_doit(fd, mainvar, chan->ipo);
+               expand_constraint_channels(fd, mainvar, &chan->constraintChannels);
+       }
+}
+
+static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
+{
+       FCurve *fcd;
+       
+       /* own action */
+       expand_doit(fd, mainvar, adt->action);
+       
+       /* drivers - assume that these F-Curves have driver data to be in this list... */
+       for (fcd= adt->drivers.first; fcd; fcd= fcd->next) {
+               ChannelDriver *driver= fcd->driver;
+               
+               expand_doit(fd, mainvar, driver->id);
+               expand_doit(fd, mainvar, driver->id2);
+       }
+}      
+
+static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
+{
+       expand_doit(fd, mainvar, part->dup_ob);
+       expand_doit(fd, mainvar, part->dup_group);
+       expand_doit(fd, mainvar, part->eff_group);
+       expand_doit(fd, mainvar, part->bb_ob);
+}
+
 static void expand_group(FileData *fd, Main *mainvar, Group *group)
 {
        GroupObject *go;
@@ -7585,14 +9165,32 @@ static void expand_group(FileData *fd, Main *mainvar, Group *group)
 
 static void expand_key(FileData *fd, Main *mainvar, Key *key)
 {
-       expand_doit(fd, mainvar, key->ipo);
+       expand_doit(fd, mainvar, key->ipo); // XXX depreceated - old animation system
+       
+       if(key->adt)
+               expand_animdata(fd, mainvar, key->adt);
 }
 
+static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
+{
+       bNode *node;
+       
+       for(node= ntree->nodes.first; node; node= node->next)
+               if(node->id && node->type!=CMP_NODE_R_LAYERS)
+                       expand_doit(fd, mainvar, node->id);
+
+}
 
 static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
 {
        expand_doit(fd, mainvar, tex->ima);
-       expand_doit(fd, mainvar, tex->ipo);
+       expand_doit(fd, mainvar, tex->ipo); // XXX depreceated - old animation system
+       
+       if(tex->adt)
+               expand_animdata(fd, mainvar, tex->adt);
+       
+       if(tex->nodetree)
+               expand_nodetree(fd, mainvar, tex->nodetree);
 }
 
 static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
@@ -7605,16 +9203,6 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
        expand_doit(fd, mainvar, brush->clone.image);
 }
 
-static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
-{
-       bNode *node;
-       
-       for(node= ntree->nodes.first; node; node= node->next)
-               if(node->id && node->type!=CMP_NODE_R_LAYERS)
-                       expand_doit(fd, mainvar, node->id);
-
-}
-
 static void expand_material(FileData *fd, Main *mainvar, Material *ma)
 {
        int a;
@@ -7626,7 +9214,10 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
                }
        }
        
-       expand_doit(fd, mainvar, ma->ipo);
+       expand_doit(fd, mainvar, ma->ipo); // XXX depreceated - old animation system
+       
+       if(ma->adt)
+               expand_animdata(fd, mainvar, ma->adt);
        
        if(ma->nodetree)
                expand_nodetree(fd, mainvar, ma->nodetree);
@@ -7642,12 +9233,16 @@ static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
                        expand_doit(fd, mainvar, la->mtex[a]->object);
                }
        }
-       expand_doit(fd, mainvar, la->ipo);
+       
+       expand_doit(fd, mainvar, la->ipo); // XXX depreceated - old animation system
+       
+       if (la->adt)
+               expand_animdata(fd, mainvar, la->adt);
 }
 
 static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt)
 {
-       expand_doit(fd, mainvar, lt->ipo);
+       expand_doit(fd, mainvar, lt->ipo); // XXX depreceated - old animation system
        expand_doit(fd, mainvar, lt->key);
 }
 
@@ -7662,7 +9257,11 @@ static void expand_world(FileData *fd, Main *mainvar, World *wrld)
                        expand_doit(fd, mainvar, wrld->mtex[a]->object);
                }
        }
-       expand_doit(fd, mainvar, wrld->ipo);
+       
+       expand_doit(fd, mainvar, wrld->ipo); // XXX depreceated - old animation system
+       
+       if (wrld->adt)
+               expand_animdata(fd, mainvar, wrld->adt);
 }
 
 
@@ -7682,15 +9281,19 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
        for(a=0; a<cu->totcol; a++) {
                expand_doit(fd, mainvar, cu->mat[a]);
        }
+       
        expand_doit(fd, mainvar, cu->vfont);
        expand_doit(fd, mainvar, cu->vfontb);   
        expand_doit(fd, mainvar, cu->vfonti);
        expand_doit(fd, mainvar, cu->vfontbi);
        expand_doit(fd, mainvar, cu->key);
-       expand_doit(fd, mainvar, cu->ipo);
+       expand_doit(fd, mainvar, cu->ipo); // XXX depreceated - old animation system
        expand_doit(fd, mainvar, cu->bevobj);
        expand_doit(fd, mainvar, cu->taperobj);
        expand_doit(fd, mainvar, cu->textoncurve);
+       
+       if(cu->adt)
+               expand_animdata(fd, mainvar, cu->adt);
 }
 
 static void expand_mesh(FileData *fd, Main *mainvar, Mesh *me)
@@ -7733,7 +9336,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
        for (curcon=lb->first; curcon; curcon=curcon->next) {
                
                if (curcon->ipo)
-                       expand_doit(fd, mainvar, curcon->ipo);
+                       expand_doit(fd, mainvar, curcon->ipo); // XXX depreceated - old animation system
                
                switch (curcon->type) {
                case CONSTRAINT_TYPE_NULL:
@@ -7835,6 +9438,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
                                expand_doit(fd, mainvar, data->tar);
                        }
                        break;
+               case CONSTRAINT_TYPE_DISTLIMIT: 
+                       {
+                               bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                       }
+                       break;
                default:
                        break;
                }
@@ -7873,23 +9482,6 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
        }
 }
 
-static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *chanbase)
-{
-       bConstraintChannel *chan;
-       for (chan=chanbase->first; chan; chan=chan->next){
-               expand_doit(fd, mainvar, chan->ipo);
-       }
-}
-
-static void expand_action(FileData *fd, Main *mainvar, bAction *act)
-{
-       bActionChannel *chan;
-       for (chan=act->chanbase.first; chan; chan=chan->next) {
-               expand_doit(fd, mainvar, chan->ipo);
-               expand_constraint_channels(fd, mainvar, &chan->constraintChannels);
-       }
-}
-
 static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
 {
        if (md->type==eModifierType_Lattice) {
@@ -7913,6 +9505,12 @@ static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
                        
                expand_doit(fd, mainvar, mmd->mirror_ob);
        }
+       else if (md->type==eModifierType_Displace) {
+               DisplaceModifierData *dmd = (DisplaceModifierData*) md;
+               
+               expand_doit(fd, mainvar, dmd->map_object);
+               expand_doit(fd, mainvar, dmd->texture);
+       }
 }
 
 static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)
@@ -7937,15 +9535,19 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 
 
        expand_doit(fd, mainvar, ob->data);
-       expand_doit(fd, mainvar, ob->ipo);
-       expand_doit(fd, mainvar, ob->action);
-
+       
        for (md=ob->modifiers.first; md; md=md->next) {
                expand_modifier(fd, mainvar, md);
        }
 
        expand_pose(fd, mainvar, ob->pose);
+       expand_doit(fd, mainvar, ob->poselib);
        expand_constraints(fd, mainvar, &ob->constraints);
+       
+// XXX depreceated - old animation system (for version patching only) 
+       expand_doit(fd, mainvar, ob->ipo);
+       expand_doit(fd, mainvar, ob->action);
+       
        expand_constraint_channels(fd, mainvar, &ob->constraintChannels);
 
        for (strip=ob->nlastrips.first; strip; strip=strip->next){
@@ -7953,7 +9555,11 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                expand_doit(fd, mainvar, strip->act);
                expand_doit(fd, mainvar, strip->ipo);
        }
-
+// XXX depreceated - old animation system (for version patching only)
+       
+       if(ob->adt)
+               expand_animdata(fd, mainvar, ob->adt);
+       
        for(a=0; a<ob->totcol; a++) {
                expand_doit(fd, mainvar, ob->mat[a]);
        }
@@ -7975,9 +9581,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 
        sens= ob->sensors.first;
        while(sens) {
-               for(a=0; a<sens->totlinks; a++) {
-                       sens->links[a]= newglobadr(fd, sens->links[a]);
-               }
                if(sens->type==SENS_TOUCH) {
                        bTouchSensor *ts= sens->data;
                        expand_doit(fd, mainvar, ts->ma);
@@ -7991,9 +9594,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 
        cont= ob->controllers.first;
        while(cont) {
-               for(a=0; a<cont->totlinks; a++) {
-                       cont->links[a]= newglobadr(fd, cont->links[a]);
-               }
                if(cont->type==CONT_PYTHON) {
                        bPythonCont *pc= cont->data;
                        expand_doit(fd, mainvar, pc->text);
@@ -8027,6 +9627,10 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                        bActionActuator *aa= act->data;
                        expand_doit(fd, mainvar, aa->act);
                }
+               else if(act->type==ACT_SHAPEACTION) {
+                       bActionActuator *aa= act->data;
+                       expand_doit(fd, mainvar, aa->act);
+               }
                else if(act->type==ACT_PROPERTY) {
                        bPropertyActuator *pa= act->data;
                        expand_doit(fd, mainvar, pa->ob);
@@ -8037,6 +9641,9 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                }
                act= act->next;
        }
+
+       if(ob->pd && ob->pd->tex)
+               expand_doit(fd, mainvar, ob->pd->tex);
        
        expand_scriptlink(fd, mainvar, &ob->scriptlink);
 }
@@ -8052,6 +9659,9 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
        expand_doit(fd, mainvar, sce->camera);
        expand_doit(fd, mainvar, sce->world);
        
+       if(sce->adt)
+               expand_animdata(fd, mainvar, sce->adt);
+       
        if(sce->nodetree)
                expand_nodetree(fd, mainvar, sce->nodetree);
        
@@ -8059,17 +9669,19 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
                expand_doit(fd, mainvar, srl->mat_override);
                expand_doit(fd, mainvar, srl->light_override);
        }
-                               
 }
 
 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
 {
-       expand_doit(fd, mainvar, ca->ipo);
+       expand_doit(fd, mainvar, ca->ipo); // XXX depreceated - old animation system
+       
+       if(ca->adt)
+               expand_animdata(fd, mainvar, ca->adt);
 }
 
 static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
 {
-       expand_doit(fd, mainvar, snd->ipo);
+       expand_doit(fd, mainvar, snd->ipo); // XXX depreceated - old animation system
 }
 
 
@@ -8136,7 +9748,7 @@ static void expand_main(FileData *fd, Main *mainvar)
                                                expand_armature(fd, mainvar, (bArmature *)id);
                                                break;
                                        case ID_AC:
-                                               expand_action(fd, mainvar, (bAction *)id);
+                                               expand_action(fd, mainvar, (bAction *)id); // XXX depreceated - old animation system
                                                break;
                                        case ID_GR:
                                                expand_group(fd, mainvar, (Group *)id);
@@ -8148,8 +9760,10 @@ static void expand_main(FileData *fd, Main *mainvar)
                                                expand_brush(fd, mainvar, (Brush *)id);
                                                break;
                                        case ID_IP:
-                                               expand_ipo(fd, mainvar, (Ipo *)id);
+                                               expand_ipo(fd, mainvar, (Ipo *)id); // XXX depreceated - old animation system
                                                break;
+                                       case ID_PA:
+                                               expand_particlesettings(fd, mainvar, (ParticleSettings *)id);
                                        }
 
                                        doit= 1;
@@ -8162,45 +9776,53 @@ static void expand_main(FileData *fd, Main *mainvar)
        }
 }
 
-static int object_in_any_scene(Object *ob)
+static int object_in_any_scene(Main *mainvar, Object *ob)
 {
        Scene *sce;
        
-       for(sce= G.main->scene.first; sce; sce= sce->id.next)
+       for(sce= mainvar->scene.first; sce; sce= sce->id.next)
                if(object_in_scene(ob, sce))
                        return 1;
        return 0;
 }
 
 /* when *lib set, it also does objects that were in the appended group */
-static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib)
+static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is_group_append)
 {
        Object *ob;
        Base *base;
 
        /* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */
-       for(ob= lb->first; ob; ob= ob->id.next) {
-
+       for(ob= mainvar->object.first; ob; ob= ob->id.next) {
+               
                if( ob->id.flag & LIB_INDIRECT ) {
-                       int do_it= 0;
                        
-                       if(ob->id.us==0)
-                               do_it= 1;
-                       else if(ob->id.us==1 && lib)
-                               if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(ob)==0)
+                               /* IF below is quite confusing!
+                               if we are appending, but this object wasnt just added allong with a group,
+                               then this is alredy used indirectly in the scene somewhere else and we didnt just append it.
+                               
+                               (ob->id.flag & LIB_APPEND_TAG)==0 means that this is a newly appended object - Campbell */
+                       if (is_group_append==0 || (ob->id.flag & LIB_APPEND_TAG)==0) {
+                               
+                               int do_it= 0;
+                               
+                               if(ob->id.us==0)
                                        do_it= 1;
+                               else if(ob->id.us==1 && lib)
+                                       if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0)
+                                               do_it= 1;
+                                               
+                               if(do_it) {
+                                       base= MEM_callocN( sizeof(Base), "add_ext_base");
+                                       BLI_addtail(&(sce->base), base);
+                                       base->lay= ob->lay;
+                                       base->object= ob;
+                                       base->flag= ob->flag;
+                                       ob->id.us= 1;
                                        
-                       if(do_it) {
-                               base= MEM_callocN( sizeof(Base), "add_ext_base");
-                               BLI_addtail(&(sce->base), base);
-                               base->lay= ob->lay;
-                               base->object= ob;
-                               base->flag= ob->flag;
-                               ob->id.us= 1;
-                               
-                               ob->id.flag -= LIB_INDIRECT;
-                               ob->id.flag |= LIB_EXTERN;
-
+                                       ob->id.flag -= LIB_INDIRECT;
+                                       ob->id.flag |= LIB_EXTERN;
+                               }
                        }
                }
        }
@@ -8245,9 +9867,9 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                        else ob= (Object *)id;
                                        
                                        /* XXX use context to find view3d->lay */
-                                       if((flag & FILE_ACTIVELAY)) {
-                                               scene->lay;
-                                       }
+                                       //if((flag & FILE_ACTIVELAY)) {
+                                       //      scene->lay;
+                                       //}
                                        base->lay= ob->lay;
                                        base->object= ob;
                                        ob->id.us++;
@@ -8288,39 +9910,39 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
 /* common routine to append/link something from a library */
 
-static Library* library_append(Scene *scene, char* file, char *dir, int idcode,
-               int totsel, FileData *fd, struct direntry* filelist, int totfile, short flag)
+static Library* library_append(Main *mainvar, Scene *scene, char* file, char *dir, int idcode,
+               int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
 {
        Main *mainl;
        Library *curlib;
 
        /* make mains */
-       blo_split_main(&fd->mainlist, G.main);
+       blo_split_main(&(*fd)->mainlist, mainvar);
 
        /* which one do we need? */
-       mainl = blo_find_main(fd, &fd->mainlist, dir, G.sce);
+       mainl = blo_find_main(*fd, &(*fd)->mainlist, dir, G.sce);
        
-       mainl->versionfile= fd->fileversion;    /* needed for do_version */
+       mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
        
        curlib= mainl->curlib;
        
        if(totsel==0) {
-               append_named_part(fd, mainl, scene, file, idcode, flag);
+               append_named_part(*fd, mainl, scene, file, idcode, flag);
        }
        else {
                int a;
                for(a=0; a<totfile; a++) {
                        if(filelist[a].flags & ACTIVE) {
-                               append_named_part(fd, mainl, scene, filelist[a].relname, idcode, flag);
+                               append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
                        }
                }
        }
 
        /* make main consistant */
-       expand_main(fd, mainl);
+       expand_main(*fd, mainl);
 
        /* do this when expand found other libs */
-       read_libraries(fd, &fd->mainlist);
+       read_libraries(*fd, &(*fd)->mainlist);
 
        if(flag & FILE_STRINGCODE) {
 
@@ -8331,25 +9953,31 @@ static Library* library_append(Scene *scene, char* file, char *dir, int idcode,
                BLI_makestringcode(G.sce, mainl->curlib->name);
        }
 
-       blo_join_main(&fd->mainlist);
-       G.main= fd->mainlist.first;
+       blo_join_main(&(*fd)->mainlist);
+       mainvar= (*fd)->mainlist.first;
 
-       lib_link_all(fd, G.main);
-       lib_verify_nodetree(G.main);
+       lib_link_all(*fd, mainvar);
+       lib_verify_nodetree(mainvar, 0);
+       fix_relpaths_library(G.sce, mainvar); /* make all relative paths, relative to the open blend file */
 
        /* give a base to loose objects. If group append, do it for objects too */
-       if(idcode==ID_GR)
-               give_base_to_objects(scene, &(G.main->object), (flag & FILE_LINK)?NULL:curlib);
-       else
-               give_base_to_objects(scene, &(G.main->object), NULL);
-       
+       if(idcode==ID_GR) {
+               if (flag & FILE_LINK) {
+                       give_base_to_objects(mainvar, scene, NULL, 0);
+               } else {
+                       give_base_to_objects(mainvar, scene, curlib, 1);
+               }       
+       } else {
+               give_base_to_objects(mainvar, scene, NULL, 0);
+       }
        /* has been removed... erm, why? s..ton) */
        /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
        /* 20041208: put back. It only linked direct, not indirect objects (ton) */
        
        /* patch to prevent switch_endian happens twice */
-       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
-               blo_freefiledata( fd );
+       if((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
+               blo_freefiledata( *fd );
+               *fd = NULL;
        }       
 
        return curlib;
@@ -8360,28 +9988,27 @@ static Library* library_append(Scene *scene, char* file, char *dir, int idcode,
 /* append to scene */
 /* this should probably be moved into the Python code anyway */
 
-void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, 
-               int idcode, short flag, Scene *scene )
+void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, 
+               int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports)
 {
+       FileData *fd= (FileData*)(*bh);
+
        /* try to append the requested object */
-       library_append(scene, name, dir, idcode, 0, (FileData *)bh, NULL, 0, flag );
+       fd->reports= reports;
+       library_append(mainvar, scene, name, dir, idcode, 0, &fd, NULL, 0, flag );
+       if(fd) fd->reports= NULL;
 
        /* do we need to do this? */
        DAG_scene_sort(scene);
-}
 
-/* append to scene */
-/* dir is a full path */       
-void BLO_library_append(SpaceFile *sfile, char *dir, int idcode, Scene *scene)
-{
-       BLO_library_append_(&sfile->libfiledata, sfile->filelist, sfile->totfile, 
-                                               dir, sfile->file, sfile->flag, idcode, scene);
+       *bh= (BlendHandle*)fd;
 }
 
-void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, 
-                                                char *dir, char* file, short flag, int idcode, Scene *scene)
+/* append to scene */
+void BLO_library_append(BlendHandle** bh, struct direntry* filelist, int totfile, 
+                                                char *dir, char* file, short flag, int idcode, Main *mainvar, Scene *scene, ReportList *reports)
 {
-       FileData *fd= (FileData*) (*libfiledata);
+       FileData *fd= (FileData*)(*bh);
        Library *curlib;
        Base *centerbase;
        Object *ob;
@@ -8401,12 +10028,12 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
                                if( strcmp(filelist[a].relname, file)==0) break;
                        }
                        if(a==totfile) {
-                               //XXX error("Wrong indicated name");
+                               BKE_report(reports, RPT_ERROR, "Wrong indicated name");
                                return;
                        }
                }
                else {
-                       //XXX error("Nothing indicated");
+                       BKE_report(reports, RPT_ERROR, "Nothing indicated");
                        return;
                }
        }
@@ -8414,12 +10041,11 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
        
        if(flag & FILE_AUTOSELECT) scene_deselect_all(scene);
 
-       curlib = library_append(scene, file, dir, idcode, totsel, fd, filelist, totfile,flag );
+       fd->reports= reports;
+       curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag );
+       if(fd) fd->reports= NULL;
 
-       /* patch to prevent switch_endian happens twice */
-       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
-               (*libfiledata)= 0;
-       }       
+       *bh= (BlendHandle*)fd;
 
        /* when not linking (appending)... */
        if((flag & FILE_LINK)==0) {
@@ -8498,9 +10124,12 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                FileData *fd= mainptr->curlib->filedata;
 
                                if(fd==NULL) {
-                                       BlendReadError err;
+                                       ReportList reports;
+
                                        printf("read library: lib %s\n", mainptr->curlib->name);
-                                       fd= blo_openblenderfile(mainptr->curlib->filename, &err);
+                                       fd= blo_openblenderfile(mainptr->curlib->filename, &reports);
+                                       fd->reports= basefd->reports;
+
                                        if (fd) {
                                                if (fd->libmap)
                                                        oldnewmap_free(fd->libmap);
@@ -8593,13 +10222,13 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                
                if(mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata);
                mainptr->curlib->filedata= NULL;
-
        }
 }
 
+
 /* reading runtime */
 
-BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r) 
+BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize, ReportList *reports)
 {
        BlendFileData *bfd = NULL;
        FileData *fd = filedata_new();
@@ -8607,11 +10236,15 @@ BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadErr
        fd->buffersize = actualsize;
        fd->read = fd_read_from_file;
 
-       fd = blo_decode_and_check(fd, error_r);
+       /* needed for library_append and read_libraries */
+       BLI_strncpy(fd->filename, name, sizeof(fd->filename));
+
+       fd = blo_decode_and_check(fd, reports);
        if (!fd)
                return NULL;
 
-       bfd= blo_read_file_internal(fd, error_r);
+       fd->reports= reports;
+       bfd= blo_read_file_internal(fd);
        blo_freefiledata(fd);
 
        return bfd;