svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r20855:20928
[blender.git] / source / blender / blenloader / intern / readfile.c
index c4d63cf..1502b47 100644 (file)
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  *
- * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Blender Foundation
  *
  * ***** END GPL LICENSE BLOCK *****
  *
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include "zlib.h"
 
 #ifdef WIN32
@@ -53,8 +48,7 @@
     #include <io.h> // for open close read
 #endif
 
-#include "nla.h"
-
+#include "DNA_anim_types.h"
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_ID.h"
@@ -69,6 +63,7 @@
 #include "DNA_customdata_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_fileglobal_types.h"
+#include "DNA_genfile.h"
 #include "DNA_group_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_ipo_types.h"
@@ -86,7 +81,7 @@
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
 #include "DNA_object_fluidsim.h" // NT
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
 #include "DNA_object_force.h"
 #include "DNA_packedFile_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_vfont_types.h"
 #include "DNA_world_types.h"
+#include "DNA_windowmanager_types.h"
 
 #include "MEM_guardedalloc.h"
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_storage_types.h" // for relname flags
 
-#include "BDR_sculptmode.h"
-
-#include "BKE_bad_level_calls.h" // for reopen_text build_seqar (from WHILE_SEQ) set_rects_butspace check_imasel_copy
-
+#include "BKE_animsys.h"
 #include "BKE_action.h"
 #include "BKE_armature.h"
+#include "BKE_brush.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_cloth.h"
 #include "BKE_colortools.h"
 #include "BKE_constraint.h"
 #include "BKE_deform.h"
 #include "BKE_depsgraph.h"
 #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" // for multires_free
+#include "BKE_multires.h"
 #include "BKE_node.h" // for tree type defines
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #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 "BIF_butspace.h" // badlevel, for do_versions, patching event codes
-#include "BIF_filelist.h" // badlevel too, where to move this? - elubie
-#include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
+//XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
+//XXX #include "BIF_filelist.h" // badlevel too, where to move this? - elubie
+//XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
 #include "BLO_readfile.h"
 #include "BLO_undofile.h"
 #include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory
 
 #include "readfile.h"
 
-#include "genfile.h"
-
-#include "mydevice.h"
-#include "blendef.h"
-
 #include "PIL_time.h"
 
 #include <errno.h>
@@ -186,7 +180,7 @@ READ
                - read associated 'direct data'
                - link direct data (internal and to LibBlock)
 - read FileGlobal
-- read USER data, only when indicated (file is ~/.B.blend)
+- read USER data, only when indicated (file is ~/.B.blend or .B25.blend)
 - free file
 - per Library (per Main)
        - read file
@@ -813,12 +807,12 @@ static int read_file_dna(FileData *fd)
                if (bhead->code==DNA1) {
                        int do_endian_swap= (fd->flags&FD_FLAGS_SWITCH_ENDIAN)?1:0;
 
-                       fd->filesdna= dna_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
+                       fd->filesdna= DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
                        if (fd->filesdna) {
                                
-                               fd->compflags= dna_get_structDNA_compareflags(fd->filesdna, fd->memsdna);
+                               fd->compflags= DNA_struct_get_compareflags(fd->filesdna, fd->memsdna);
                                /* used to retrieve ID names from (bhead+1) */
-                               fd->id_name_offs= dna_elem_offset(fd->filesdna, "ID", "char", "name[]");
+                               fd->id_name_offs= DNA_elem_offset(fd->filesdna, "ID", "char", "name[]");
                        }
 
                        return 1;
@@ -829,7 +823,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);
 
@@ -842,7 +836,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);
 
@@ -855,7 +849,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);
@@ -866,7 +860,7 @@ 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 */
@@ -927,8 +921,6 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
 
 static FileData *filedata_new(void)
 {
-       extern unsigned char DNAstr[];  /* DNA.c */
-       extern int DNAlen;
        FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
 
        fd->filedes = -1;
@@ -938,7 +930,7 @@ static FileData *filedata_new(void)
                 * but it keeps us reentrant,  remove once we have
                 * a lib that provides a nice lock. - zr
                 */
-       fd->memsdna = dna_sdna_from_data(DNAstr,  DNAlen,  0);
+       fd->memsdna = DNA_sdna_from_data(DNAstr,  DNAlen,  0);
 
        fd->datamap = oldnewmap_new();
        fd->globmap = oldnewmap_new();
@@ -947,19 +939,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;
        }
@@ -969,14 +961,14 @@ 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();
@@ -986,14 +978,14 @@ FileData *blo_openblenderfile(char *name, BlendReadError *error_r)
                /* needed for library_append and read_libraries */
                BLI_strncpy(fd->filename, name, sizeof(fd->filename));
 
-               return blo_decode_and_check(fd, error_r);
+               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();
@@ -1002,14 +994,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();
@@ -1018,7 +1010,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);
        }
 }
 
@@ -1045,9 +1037,9 @@ void blo_freefiledata(FileData *fd)
                BLI_freelistN(&fd->listbase);
 
                if (fd->memsdna)
-                       dna_freestructDNA(fd->memsdna);
+                       DNA_sdna_free(fd->memsdna);
                if (fd->filesdna)
-                       dna_freestructDNA(fd->filesdna);
+                       DNA_sdna_free(fd->filesdna);
                if (fd->compflags)
                        MEM_freeN(fd->compflags);
 
@@ -1143,20 +1135,19 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi
  * 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)
+void blo_clear_proxy_pointers_from_lib(FileData *fd, Main *oldmain)
 {
-       Object *ob= G.main->object.first;
+       Object *ob= oldmain->object.first;
        
        for(;ob; ob= ob->id.next)
                if(ob->id.lib)
                        ob->proxy_from= NULL;
 }
 
-/* assumed; G.main still exists */
-void blo_make_image_pointer_map(FileData *fd)
+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();
        
@@ -1176,13 +1167,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 */
@@ -1245,7 +1236,7 @@ static void switch_endian_structs(struct SDNA *filesdna, BHead *bhead)
 
        nblocks= bhead->nr;
        while(nblocks--) {
-               dna_switch_endian_struct(filesdna, bhead->SDNAnr, data);
+               DNA_struct_switch_endian(filesdna, bhead->SDNAnr, data);
 
                data+= blocksize;
        }
@@ -1262,7 +1253,7 @@ static void *read_struct(FileData *fd, BHead *bh, char *blockname)
 
                if (fd->compflags[bh->SDNAnr]) {        /* flag==0: doesn't exist anymore */
                        if(fd->compflags[bh->SDNAnr]==2) {
-                               temp= dna_reconstruct(fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh+1));
+                               temp= DNA_struct_reconstruct(fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh+1));
                        } else {
                                temp= MEM_mallocN(bh->len, blockname);
                                memcpy(temp, (bh+1), bh->len);
@@ -1366,11 +1357,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);
+       }
+}
 
-static 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.*/
@@ -1378,26 +1388,33 @@ static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd)
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
        if (switch_endian) {
-               if (prop->subtype != IDP_DOUBLE) {
+               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_INT(((int*)prop->data.pointer)[i]);
+                               SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
                        }
                } else {
                        for (i=0; i<prop->len; i++) {
-                               SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
+                               SWITCH_INT(((int*)prop->data.pointer)[i]);
                        }
                }
        }
 }
 
-static 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);
 }
 
-static 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;
@@ -1410,7 +1427,7 @@ static 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:
@@ -1422,6 +1439,9 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
                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
@@ -1444,10 +1464,26 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
 }
 
 /*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 *************** */
 /* library brush linking after fileread */
 static void lib_link_brush(FileData *fd, Main *main)
@@ -1468,6 +1504,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);
                }
        }
 }
@@ -1479,6 +1517,13 @@ static void direct_link_brush(FileData *fd, Brush *brush)
 
        for(a=0; a<MAX_MTEX; a++)
                brush->mtex[a]= newdataadr(fd, brush->mtex[a]);
+
+       /* fallof curve */
+       brush->curve= newdataadr(fd, brush->curve);
+       if(brush->curve)
+               direct_link_curvemapping(fd, brush->curve);
+       else
+               brush_curve_preset(brush, BRUSH_PRESET_SHARP);
 }
 
 static void direct_link_script(FileData *fd, Script *script)
@@ -1487,22 +1532,355 @@ static void direct_link_script(FileData *fd, Script *script)
        SCRIPT_SET_NULL(script)
 }
 
-/* ************ READ CurveMapping *************** */
 
-/* cuma itself has been read! */
-static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
+/* ************ READ PACKEDFILE *************** */
+
+static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
 {
-       int a;
+       PackedFile *pf= newdataadr(fd, oldpf);
+
+       if (pf) {
+               pf->data= newdataadr(fd, pf->data);
+       }
+
+       return pf;
+}
+
+/* ************ READ IMAGE PREVIEW *************** */
+
+static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv)
+{
+       PreviewImage *prv= newdataadr(fd, old_prv);
+
+       if (prv) {
+               int i;
+               for (i=0; i < PREVIEW_MIPMAPS; ++i) {
+                       if (prv->rect[i]) {
+                               prv->rect[i] = newdataadr(fd, prv->rect[i]);
+                       }
+               }
+       }
+
+       return prv;
+}
+
+/* ************ READ SCRIPTLINK *************** */
+
+static void lib_link_scriptlink(FileData *fd, ID *id, ScriptLink *slink)
+{
+       int i;
+
+       for(i=0; i<slink->totscript; i++) {
+               slink->scripts[i]= newlibadr(fd, id->lib, slink->scripts[i]);
+       }
+}
+
+static void direct_link_scriptlink(FileData *fd, ScriptLink *slink)
+{
+       slink->scripts= newdataadr(fd, slink->scripts);
+       test_pointer_array(fd, (void **)&slink->scripts);
        
-       /* flag seems to be able to hang? Maybe old files... not bad to clear anyway */
-       cumap->flag &= ~CUMA_PREMULLED;
+       slink->flag= newdataadr(fd, slink->flag);
+
+       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+               int a;
+
+               for(a=0; a<slink->totscript; a++) {
+                       SWITCH_SHORT(slink->flag[a]);
+               }
+       }
+}
+
+/* ************ 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;
+       bActionModifier *amod;
        
-       for(a=0; a<CM_TOT; a++) {
-               cumap->cm[a].curve= newdataadr(fd, cumap->cm[a].curve);
-               cumap->cm[a].table= NULL;
+       for (strip=striplist->first; strip; strip=strip->next){
+               strip->object = newlibadr(fd, id->lib, strip->object);
+               strip->act = newlibadr_us(fd, id->lib, strip->act);
+               strip->ipo = newlibadr(fd, id->lib, strip->ipo);
+               for(amod= strip->modifiers.first; amod; amod= amod->next)
+                       amod->ob= newlibadr(fd, id->lib, amod->ob);
+       }
+}
+
+// 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;
+
+       for (chan=chanbase->first; chan; chan=chan->next){
+               chan->ipo = newlibadr_us(fd, id->lib, chan->ipo);
+       }
+}
+
+/* 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;
+                       DriverTarget *dtar;
+                       
+                       for (dtar= driver->targets.first; dtar; dtar= dtar->next)
+                               dtar->id= newlibadr(fd, id->lib, dtar->id); 
+               }
+               
+               /* 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;
+                       DriverTarget *dtar;
+                       
+                       /* relink targets and their paths */
+                       link_list(fd, &driver->targets);
+                       for (dtar= driver->targets.first; dtar; dtar= dtar->next)
+                               dtar->rna_path= newdataadr(fd, dtar->rna_path);
+               }
+               
+               /* modifiers */
+               link_list(fd, &fcu->modifiers);
+               for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
+                       /* relink general data */
+                       fcm->data = newdataadr(fd, fcm->data);
+                       fcm->edata= NULL;
+                       
+                       /* do relinking of data for specific types */
+                       switch (fcm->type) {
+                               case FMODIFIER_TYPE_GENERATOR:
+                               {
+                                       FMod_Generator *data= (FMod_Generator *)fcm->data;
+                                       
+                                       data->coefficients= newdataadr(fd, data->coefficients);
+                               }
+                                       break;
+                               case FMODIFIER_TYPE_ENVELOPE:
+                               {
+                                       FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+                                       
+                                       data->data= newdataadr(fd, data->data);
+                               }
+                                       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_keyingsets(FileData *fd, ID *id, ListBase *list)
+{
+       KeyingSet *ks;
+       KS_Path *ksp;
+       
+       /* here, we're only interested in the ID pointer stored in some of the paths */
+       for (ks= list->first; ks; ks= ks->next) {
+               for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+                       ksp->id= newlibadr(fd, id->lib, ksp->id); 
+               }
+       }
+}
+
+/* NOTE: this assumes that link_list has already been called on the list */
+static void direct_link_keyingsets(FileData *fd, ListBase *list)
+{
+       KeyingSet *ks;
+       KS_Path *ksp;
+       
+       /* link KeyingSet data to KeyingSet again (non ID-libs) */
+       for (ks= list->first; ks; ks= ks->next) {
+               /* paths */
+               link_list(fd, &ks->paths);
+               
+               for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+                       /* rna path */
+                       ksp->rna_path= newdataadr(fd, ksp->rna_path);
+               }
+       }
+}
+
+/* ------- */
+
+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 NODE TREE *************** */
 
 /* singe node tree (also used for material/scene trees), ntree is not NULL */
@@ -1510,6 +1888,8 @@ static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree)
 {
        bNode *node;
        
+       if(ntree->adt) lib_link_animdata(fd, &ntree->id, ntree->adt);
+       
        for(node= ntree->nodes.first; node; node= node->next)
                node->id= newlibadr_us(fd, id->lib, node->id);
 }
@@ -1530,18 +1910,18 @@ static void lib_link_nodetree(FileData *fd, Main *main)
 
 /* verify types for nodes and groups, all data has to be read */
 /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
- * typedefs*/
+* 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();
-       }*/
+               if(open==1) {
+                       reinit_nodesystem();
+               }*/
        
        /* now create the own typeinfo structs an verify nodes */
        /* here we still assume no groups in groups */
@@ -1581,6 +1961,9 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        ntree->owntype= NULL;
        ntree->timecursor= NULL;
        
+       ntree->adt= newdataadr(fd, ntree->adt);
+       direct_link_animdata(fd, ntree->adt);
+       
        link_list(fd, &ntree->nodes);
        for(node= ntree->nodes.first; node; node= node->next) {
                if(node->type == NODE_DYNAMIC) {
@@ -1588,7 +1971,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                        node->custom1= BSET(node->custom1, NODE_DYNAMIC_LOADED);
                        node->typeinfo= NULL;
                }
-
+               
                node->storage= newdataadr(fd, node->storage);
                if(node->storage) {
                        
@@ -1645,89 +2028,8 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        /* type verification is in lib-link */
 }
 
-/* ************ READ PACKEDFILE *************** */
-
-static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
-{
-       PackedFile *pf= newdataadr(fd, oldpf);
-
-       if (pf) {
-               pf->data= newdataadr(fd, pf->data);
-       }
-
-       return pf;
-}
-
-/* ************ READ IMAGE PREVIEW *************** */
-
-static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv)
-{
-       PreviewImage *prv= newdataadr(fd, old_prv);
-
-       if (prv) {
-               int i;
-               for (i=0; i < PREVIEW_MIPMAPS; ++i) {
-                       if (prv->rect[i]) {
-                               prv->rect[i] = newdataadr(fd, prv->rect[i]);
-                       }
-               }
-       }
-
-       return prv;
-}
-
-/* ************ READ SCRIPTLINK *************** */
-
-static void lib_link_scriptlink(FileData *fd, ID *id, ScriptLink *slink)
-{
-       int i;
-
-       for(i=0; i<slink->totscript; i++) {
-               slink->scripts[i]= newlibadr(fd, id->lib, slink->scripts[i]);
-       }
-}
-
-static void direct_link_scriptlink(FileData *fd, ScriptLink *slink)
-{
-       slink->scripts= newdataadr(fd, slink->scripts);
-       test_pointer_array(fd, (void **)&slink->scripts);
-       
-       slink->flag= newdataadr(fd, slink->flag);
-
-       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
-               int a;
-
-               for(a=0; a<slink->totscript; a++) {
-                       SWITCH_SHORT(slink->flag[a]);
-               }
-       }
-}
-
 /* ************ READ ARMATURE ***************** */
 
-static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
-{
-       bActionStrip *strip;
-       bActionModifier *amod;
-       
-       for (strip=striplist->first; strip; strip=strip->next){
-               strip->object = newlibadr(fd, id->lib, strip->object);
-               strip->act = newlibadr_us(fd, id->lib, strip->act);
-               strip->ipo = newlibadr(fd, id->lib, strip->ipo);
-               for(amod= strip->modifiers.first; amod; amod= amod->next)
-                       amod->ob= newlibadr(fd, id->lib, amod->ob);
-       }
-}
-
-static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase)
-{
-       bConstraintChannel *chan;
-
-       for (chan=chanbase->first; chan; chan=chan->next){
-               chan->ipo = newlibadr_us(fd, id->lib, chan->ipo);
-       }
-}
-
 static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
 {
        bConstraint *con;
@@ -1739,7 +2041,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:
@@ -1884,9 +2186,12 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
                
                if (cons->type == CONSTRAINT_TYPE_PYTHON) {
                        bPythonConstraint *data= cons->data;
+                       
                        link_list(fd, &data->targets);
+                       
                        data->prop = newdataadr(fd, data->prop);
-                       IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                       if (data->prop)
+                               IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
                }
        }
 }
@@ -1939,26 +2244,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;
@@ -1972,36 +2257,13 @@ static void direct_link_bones(FileData *fd, Bone* bone)
        }
 }
 
-
-static void direct_link_action(FileData *fd, bAction *act)
-{
-       bActionChannel *achan;
-       bActionGroup *agrp;
-
-       link_list(fd, &act->chanbase);
-       link_list(fd, &act->groups);
-       link_list(fd, &act->markers);
-
-       for (achan = act->chanbase.first; achan; achan=achan->next) {
-               achan->grp= newdataadr(fd, achan->grp);
-               
-               link_list(fd, &achan->constraintChannels);
-       }
-               
-       for (agrp = act->groups.first; agrp; agrp= agrp->next) {
-               if (agrp->channels.first) {
-                       agrp->channels.first= newdataadr(fd, agrp->channels.first);
-                       agrp->channels.last= newdataadr(fd, agrp->channels.last);
-               }
-       }
-}
-
 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);
@@ -2018,13 +2280,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;
@@ -2033,6 +2296,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);
 }
 
@@ -2048,7 +2314,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) {
@@ -2056,11 +2323,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;
@@ -2070,7 +2337,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++) {
@@ -2093,8 +2363,9 @@ static void lib_link_key(FileData *fd, Main *main)
        key= main->key.first;
        while(key) {
                if(key->id.flag & LIB_NEEDLINK) {
-
-                       key->ipo= newlibadr_us(fd, key->id.lib, key->ipo);
+                       if(key->adt) lib_link_animdata(fd, &key->id, key->adt);
+                       
+                       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;
@@ -2143,6 +2414,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;
@@ -2170,7 +2444,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;
                }
@@ -2185,9 +2459,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 ***************** */
@@ -2201,9 +2475,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) {
@@ -2211,9 +2486,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;
@@ -2224,6 +2499,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++) {
@@ -2233,40 +2511,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)
@@ -2340,7 +2584,7 @@ static void direct_link_text(FileData *fd, Text *text)
                ln= ln->next;
        }
 
-       text->flags = (text->flags|TXT_ISTMP) & ~TXT_ISEXT;
+       text->flags = (text->flags) & ~TXT_ISEXT;
 
        text->id.us= 1;
 }
@@ -2414,6 +2658,7 @@ static void lib_link_curve(FileData *fd, Main *main)
        cu= main->curve.first;
        while(cu) {
                if(cu->id.flag & LIB_NEEDLINK) {
+                       if(cu->adt) lib_link_animdata(fd, &cu->id, cu->adt);
 
                        for(a=0; a<cu->totcol; a++) cu->mat[a]= newlibadr_us(fd, cu->id.lib, cu->mat[a]);
 
@@ -2425,7 +2670,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;
@@ -2457,7 +2702,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);
@@ -2482,10 +2730,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->editfont= NULL;
+       
        nu= cu->nurb.first;
        while(nu) {
                nu->bezt= newdataadr(fd, nu->bezt);
@@ -2512,6 +2763,7 @@ static void lib_link_texture(FileData *fd, Main *main)
        tex= main->tex.first;
        while(tex) {
                if(tex->id.flag & LIB_NEEDLINK) {
+                       if(tex->adt) lib_link_animdata(fd, &tex->id, tex->adt);
 
                        tex->ima= newlibadr_us(fd, tex->id.lib, tex->ima);
                        tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
@@ -2528,6 +2780,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;
@@ -2568,6 +2823,8 @@ static void lib_link_material(FileData *fd, Main *main)
        ma= main->mat.first;
        while(ma) {
                if(ma->id.flag & LIB_NEEDLINK) {
+                       if(ma->adt) lib_link_animdata(fd, &ma->id, ma->adt);
+
                        /*Link ID Properties -- and copy this comment EXACTLY for easy finding
                        of library blocks that implement this.*/
                        if (ma->id.properties) IDP_LibLinkProperty(ma->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
@@ -2597,6 +2854,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]);
        }
@@ -2629,7 +2889,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);
@@ -2714,6 +2974,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                }
 
                psys->edit = 0;
+               psys->free_edit = NULL;
                psys->pathcache = 0;
                psys->childcache = 0;
                psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
@@ -2803,6 +3064,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;
@@ -2814,6 +3088,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++;
                }
        }
@@ -2852,7 +3128,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) {
@@ -2865,11 +3142,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)
@@ -2882,9 +3154,6 @@ 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;
                }
        }
 
@@ -2902,7 +3171,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        
        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]);
@@ -2923,7 +3192,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;
@@ -2938,6 +3207,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;
 }
 
 
@@ -2972,11 +3243,15 @@ 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);
                        
@@ -2995,7 +3270,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);
                           
@@ -3012,15 +3287,18 @@ static void lib_link_object(FileData *fd, Main *main)
                                }
                        }
                        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) {
@@ -3158,7 +3436,8 @@ static void lib_link_object(FileData *fd, Main *main)
                ob= ob->id.next;
        }
 
-       if(warn) error("WARNING IN CONSOLE");
+       if(warn)
+               BKE_report(fd->reports, RPT_WARNING, "Warning in console");
 }
 
 
@@ -3176,7 +3455,13 @@ static void direct_link_pose(FileData *fd, bPose *pose)
                pchan->bone= NULL;
                pchan->parent= newdataadr(fd, pchan->parent);
                pchan->child= newdataadr(fd, pchan->child);
+               
                direct_link_constraints(fd, &pchan->constraints);
+               
+               pchan->prop = newdataadr(fd, pchan->prop);
+               if (pchan->prop)
+                       IDP_DirectLinkProperty(pchan->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               
                pchan->iktree.first= pchan->iktree.last= NULL;
                pchan->path= NULL;
        }
@@ -3190,6 +3475,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))
@@ -3305,19 +3591,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;
@@ -3331,13 +3613,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);
 
@@ -3508,14 +3795,23 @@ static void direct_link_object(FileData *fd, Object *ob)
 
 /* ************ READ SCENE ***************** */
 
+/* patch for missing scene IDs, can't be in do-versions */
+static void composite_patch(bNodeTree *ntree, Scene *scene)
+{
+       bNode *node;
+       
+       for(node= ntree->nodes.first; node; node= node->next)
+               if(node->id==NULL && ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE))
+                       node->id= &scene->id;
+}
+
+
 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) {
@@ -3523,24 +3819,29 @@ 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);
+                       
+                       lib_link_keyingsets(fd, &sce->id, &sce->keyingsets);
+                       
                        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);
-
-       
+                       if(sce->toolsettings->sculpt)
+                               sce->toolsettings->sculpt->brush=
+                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->sculpt->brush);
+                       if(sce->toolsettings->vpaint)
+                               sce->toolsettings->vpaint->brush=
+                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->vpaint->brush);
+                       if(sce->toolsettings->wpaint)
+                               sce->toolsettings->wpaint->brush=
+                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->wpaint->brush);
+                       
                        sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
 
-                       /* 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);
-                       }
-
                        for(base= sce->base.first; base; base= next) {
                                next= base->next;
 
@@ -3557,29 +3858,33 @@ static void lib_link_scene(FileData *fd, Main *main)
                                        MEM_freeN(base);
                                }
                        }
-
-                       ed= sce->ed;
-                       if(ed) {
-                               WHILE_SEQ(&ed->seqbase) {
-                                       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);
                        
-                       if(sce->nodetree)
+                       if(sce->nodetree) {
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
+                               composite_patch(sce->nodetree, sce);
+                       }
                        
                        for(srl= sce->r.layers.first; srl; srl= srl->next) {
                                srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override);
@@ -3600,11 +3905,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)
@@ -3612,41 +3916,48 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
-       int a;
 
        sce->theDag = NULL;
        sce->dagisvalid = 0;
+       sce->obedit= NULL;
+       
        /* set users to one by default, not in lib-link, this will increase it for compo nodes */
        sce->id.us= 1;
 
        link_list(fd, &(sce->base));
-
+       
+       sce->adt= newdataadr(fd, sce->adt);
+       direct_link_animdata(fd, sce->adt);
+       
+       link_list(fd, &sce->keyingsets);
+       direct_link_keyingsets(fd, &sce->keyingsets);
+       
        sce->basact= newdataadr(fd, sce->basact);
 
        sce->radio= newdataadr(fd, sce->radio);
        
        sce->toolsettings= newdataadr(fd, sce->toolsettings);
+       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);
+               sce->toolsettings->imapaint.paintcursor= NULL;
+               sce->toolsettings->particle.paintcursor= NULL;
 
-       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
-               sculpt_reset_curve(&sce->sculptdata);
+               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) {
+               SEQ_BEGIN(ed, seq) {
                        seq->seq1= newdataadr(fd, seq->seq1);
                        seq->seq2= newdataadr(fd, seq->seq2);
                        seq->seq3= newdataadr(fd, seq->seq3);
@@ -3705,7 +4016,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                                }
                        }
                }
-               END_SEQ
+               SEQ_END
                
                /* link metastack, slight abuse of structs here, have to restore pointer to internal part in struct */
                {
@@ -3779,75 +4090,67 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        
 }
 
-/* Nasty exception; IpoWindow stores a non-ID pointer in *from for sequence
-   strips... bad code warning! 
+/* ************ READ WM ***************** */
 
-   We work around it by retrieving the missing pointer from the corresponding
-   Sequence-structure. 
-
-   This is needed, to make Ipo-Pinning work for Sequence-Ipos...
-*/
-static Sequence * find_sequence_from_ipo_helper(Main * main, Ipo * ipo)
+static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
 {
-       Editing *ed;
-       Sequence *seq = NULL;
-
-       Scene * sce= main->scene.first;
-       while(sce) {
-               if(sce->ed) {
-                       int found = 0;
+       wmWindow *win;
+       
+       wm->id.us= 1;
+       link_list(fd, &(wm->windows));
+       
+       for(win= wm->windows.first; win; win= win->next) {
+               win->ghostwin= NULL;
+               win->eventstate= NULL;
+               win->curswin= NULL;
+               win->tweak= NULL;
 
-                       ed= sce->ed;
+               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->gesture.first= win->gesture.last= NULL;
 
-                       WHILE_SEQ(&ed->seqbase) {
-                               if (seq->ipo == ipo) {
-                                       found = 1;
-                                       break;
-                               }
-                       } 
-                       END_SEQ
-                       if (found) {
-                               break;
-                       }
-                       seq = NULL;
-               }
-               sce= sce->id.next;
+               win->drawdata= NULL;
+               win->drawmethod= -1;
+               win->drawfail= 0;
        }
-       if (seq)
-        return seq;
-       else
-               return NULL;
+       
+       wm->operators.first= wm->operators.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;
+       
+       wm->windrawable= NULL;
+       wm->initialized= 0;
 }
 
-static void lib_link_screen_sequence_ipos(Main *main)
+static void lib_link_windowmanager(FileData *fd, Main *main)
 {
-       bScreen *sc;
-       ScrArea *sa;
-
-       for(sc= main->screen.first; sc; sc= sc->id.next) {
-               for(sa= sc->areabase.first; sa; sa= sa->next) {
-                       SpaceLink *sl;
-                       for (sl= sa->spacedata.first; sl; sl= sl->next) {
-                               if(sl->spacetype == SPACE_IPO) {
-                                       SpaceIpo *sipo= (SpaceIpo *)sl;
-                                       if(sipo->blocktype==ID_SEQ) {
-                                               sipo->from = (ID*) find_sequence_from_ipo_helper(main, sipo->ipo);
-                                       }
-                               }
-                       }
+       wmWindowManager *wm;
+       
+       for(wm= main->wm.first; wm; wm= wm->id.next) {
+               wmWindow *win;
+               for(win= wm->windows.first; win; win= win->next) {
+                       win->screen= newlibadr(fd, NULL, win->screen);
                }
        }
 }
 
-/* ************ 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)
+/* relinks grease-pencil data - used for direct_link and old file linkage */
+static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
 {
        bGPDlayer *gpl;
        bGPDframe *gpf;
        bGPDstroke *gps;
        
+       /* we must firstly have some grease-pencil data to link! */
+       if (gpd == NULL)
+               return;
+       
        /* relink layers */
        link_list(fd, &gpd->layers);
        
@@ -3867,6 +4170,29 @@ static void link_gpencil(FileData *fd, bGPdata *gpd)
        }
 }
 
+/* ****************** 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 */
 static void lib_link_screen(FileData *fd, Main *main)
@@ -3901,33 +4227,27 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                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;
-                                               sipo->editipo= 0;
-                                               
-                                               if(sipo->blocktype==ID_SEQ) sipo->from= NULL;   // no libdata
-                                               else sipo->from= newlibadr(fd, sc->id.lib, sipo->from);
                                                
-                                               sipo->ipokey.first= sipo->ipokey.last= 0;
-                                               sipo->ipo= newlibadr(fd, sc->id.lib, sipo->ipo);
+                                               if(sipo->ads)
+                                                       sipo->ads->source= newlibadr(fd, sc->id.lib, sipo->ads->source);
                                        }
                                        else if(sl->spacetype==SPACE_BUTS) {
                                                SpaceButs *sbuts= (SpaceButs *)sl;
                                                sbuts->lockpoin= NULL;
                                                sbuts->ri= NULL;
-                                               if(main->versionfile<132) set_rects_butspace(sbuts);
+                                               sbuts->pinid= newlibadr(fd, sc->id.lib, sbuts->pinid);
+                                               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->menup= NULL;
-                                               sfile->pupmenu= NULL;
+                                               sfile->files= NULL;
+                                               sfile->params= NULL;
+                                               sfile->op= NULL;
+                                               sfile->layout= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_IMASEL) {
                                                SpaceImaSel *simasel= (SpaceImaSel *)sl;
@@ -3941,6 +4261,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;
@@ -3967,18 +4288,11 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                        }
                                                }
                                        }
-                                       else if(sl->spacetype==SPACE_OOPS) {
+                                       else if(sl->spacetype==SPACE_OUTLINER) {
                                                SpaceOops *so= (SpaceOops *)sl;
-                                               Oops *oops;
                                                TreeStoreElem *tselem;
                                                int a;
 
-                                               oops= so->oops.first;
-                                               while(oops) {
-                                                       oops->id= newlibadr(fd, NULL, oops->id);
-                                                       oops= oops->next;
-                                               }
-                                               so->lockpoin= NULL;
                                                so->tree.first= so->tree.last= NULL;
                                                so->search_tse.id= newlibadr(fd, NULL, so->search_tse.id);
                                                
@@ -3994,6 +4308,21 @@ static void lib_link_screen(FileData *fd, Main *main)
 
                                                ssound->sound= newlibadr_us(fd, sc->id.lib, ssound->sound);
                                        }
+                                       else if(sl->spacetype==SPACE_NODE) {
+                                               SpaceNode *snode= (SpaceNode *)sl;
+                                               
+                                               snode->id= newlibadr(fd, sc->id.lib, snode->id);
+                                               
+                                               /* internal data, a bit patchy */
+                                               if(snode->id) {
+                                                       if(GS(snode->id->name)==ID_MA)
+                                                               snode->nodetree= ((Material *)snode->id)->nodetree;
+                                                       else if(GS(snode->id->name)==ID_SCE)
+                                                               snode->nodetree= ((Scene *)snode->id)->nodetree;
+                                                       else if(GS(snode->id->name)==ID_TE)
+                                                               snode->nodetree= ((Tex *)snode->id)->nodetree;
+                                               }
+                                       }
                                }
                                sa= sa->next;
                        }
@@ -4031,11 +4360,26 @@ 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= restore_pointer_by_name(newmain, (ID *)sc->scene, 1);
@@ -4069,29 +4413,33 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                                v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
                                        }
                                        if(v3d->localvd) {
-                                               Base *base;
+                                               /*Base *base;*/
 
                                                v3d->localvd->camera= sc->scene->camera;
                                                
                                                /* localview can become invalid during undo/redo steps, so we exit it when no could be found */
+                                               /* XXX  regionlocalview ?
                                                for(base= sc->scene->base.first; base; base= base->next) {
                                                        if(base->lay & v3d->lay) break;
                                                }
                                                if(base==NULL) {
                                                        v3d->lay= v3d->localvd->lay;
                                                        v3d->layact= v3d->localvd->layact;
-                                                       MEM_freeN(v3d->localvd);
+                                                       MEM_freeN(v3d->localvd); 
                                                        v3d->localvd= NULL;
                                                        v3d->localview= 0;
                                                }
+                                               */
                                        }
                                        else if(v3d->scenelock) v3d->lay= sc->scene->lay;
-                                       
+
                                        /* not very nice, but could help */
                                        if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay;
                                        
                                }
                                else if(sl->spacetype==SPACE_IPO) {
+                                       /* XXX animato */
+#if 0
                                        SpaceIpo *sipo= (SpaceIpo *)sl;
 
                                        sipo->ipo= restore_pointer_by_name(newmain, (ID *)sipo->ipo, 0);
@@ -4103,27 +4451,36 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                        // not free sipo->ipokey, creates dependency with src/
                                        if(sipo->editipo) MEM_freeN(sipo->editipo);
                                        sipo->editipo= NULL;
+#endif
                                }
                                else if(sl->spacetype==SPACE_BUTS) {
                                        SpaceButs *sbuts= (SpaceButs *)sl;
                                        sbuts->lockpoin= NULL;
-                                       if (sbuts->ri) sbuts->ri->curtile = 0;
+                                       sbuts->pinid = restore_pointer_by_name(newmain, sbuts->pinid, 0);
+                                       //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;
                                        if (simasel->files) {
-                                               BIF_filelist_freelib(simasel->files);
+                                               //XXX BIF_filelist_freelib(simasel->files);
                                        }
                                }
                                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;
@@ -4149,17 +4506,10 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                                SCRIPT_SET_NULL(scpt->script)
                                        }
                                }
-                               else if(sl->spacetype==SPACE_OOPS) {
+                               else if(sl->spacetype==SPACE_OUTLINER) {
                                        SpaceOops *so= (SpaceOops *)sl;
-                                       Oops *oops;
                                        int a;
                                        
-                                       oops= so->oops.first;
-                                       while(oops) {
-                                               oops->id= restore_pointer_by_name(newmain, (ID *)oops->id, 0);
-                                               oops= oops->next;
-                                       }
-                                       so->lockpoin= NULL;
                                        so->search_tse.id= restore_pointer_by_name(newmain, so->search_tse.id, 0);
                                        
                                        if(so->treestore) {
@@ -4178,8 +4528,19 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                else if(sl->spacetype==SPACE_NODE) {
                                        SpaceNode *snode= (SpaceNode *)sl;
                                        
-                                       snode->nodetree= snode->edittree= NULL;
-                                       snode->flag |= SNODE_DO_PREVIEW;
+                                       snode->id= restore_pointer_by_name(newmain, snode->id, 1);
+                                       snode->edittree= NULL;
+                                       
+                                       if(snode->id==NULL)
+                                               snode->nodetree= NULL;
+                                       else {
+                                               if(GS(snode->id->name)==ID_MA)
+                                                       snode->nodetree= ((Material *)snode->id)->nodetree;
+                                               else if(GS(snode->id->name)==ID_SCE)
+                                                       snode->nodetree= ((Scene *)snode->id)->nodetree;
+                                               else if(GS(snode->id->name)==ID_TE)
+                                                       snode->nodetree= ((Tex *)snode->id)->nodetree;
+                                       }
                                }
                        }
                        sa= sa->next;
@@ -4187,19 +4548,82 @@ 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->runtime_flag= 0;
+               pa->activedata= NULL;
+               pa->type= 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;
+                       rv3d->lastmode= 0;
+               }
+       }
+       
+       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;
+       ar->do_draw= 0;
+       memset(&ar->drawrct, 0, sizeof(ar->drawrct));
+}
+
+/* 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 patch");
+                       rv3d->persp= v3d->persp;
+                       rv3d->view= v3d->view;
+                       rv3d->dist= v3d->dist;
+                       VECCOPY(rv3d->ofs, v3d->ofs);
+                       QUATCOPY(rv3d->viewquat, v3d->viewquat);
+               }
+       }
+}
+
 static void direct_link_screen(FileData *fd, bScreen *sc)
 {
        ScrArea *sa;
        ScrVert *sv;
        ScrEdge *se;
-       Oops *oops;
        int a;
        
        link_list(fd, &(sc->vertbase));
        link_list(fd, &(sc->edgebase));
        link_list(fd, &(sc->areabase));
-       sc->winakt= 0;
+       sc->regionbase.first= sc->regionbase.last= NULL;
+       sc->context= NULL;
 
+       sc->mainwin= sc->subwinactive= 0;       /* indices */
+       sc->swap= 0;
+       
        /* hacky patch... but people have been saving files with the verse-blender,
           causing the handler to keep running for ever, with no means to disable it */
        for(a=0; a<SCREEN_MAXHANDLER; a+=2) {
@@ -4210,8 +4634,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
        }
        
        /* edges */
-       se= sc->edgebase.first;
-       while(se) {
+       for(se= sc->edgebase.first; se; se= se->next) {
                se->v1= newdataadr(fd, se->v1);
                se->v2= newdataadr(fd, se->v2);
                if( (intptr_t)se->v1 > (intptr_t)se->v2) {
@@ -4224,29 +4647,39 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                        printf("error reading screen... file corrupt\n");
                        se->v1= se->v2;
                }
-               se= se->next;
        }
 
        /* areas */
-       sa= sc->areabase.first;
-       while(sa) {
-               Panel *pa;
+       for(sa= sc->areabase.first; sa; sa= sa->next) {
                SpaceLink *sl;
+               ARegion *ar;
 
                link_list(fd, &(sa->spacedata));
-               link_list(fd, &(sa->panels));
+               link_list(fd, &(sa->regionbase));
 
-               /* accident can happen when read/save new file with older version */
-               if(sa->spacedata.first==NULL && sa->spacetype>SPACE_NLA)
-                       sa->spacetype= SPACE_EMPTY;
+               sa->handlers.first= sa->handlers.last= NULL;
+               sa->type= NULL; /* spacetype callbacks */
                
-               for(pa= sa->panels.first; pa; pa=pa->next) {
-                       pa->paneltab= newdataadr(fd, pa->paneltab);
-                       pa->active= 0;
-                       pa->sortcounter= 0;
-               }
+               for(ar= sa->regionbase.first; ar; ar= ar->next)
+                       direct_link_region(fd, ar, sa->spacetype);
+               
+               /* 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= sinfo->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);
@@ -4254,23 +4687,22 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                        v3d->bgpic->iuser.ok= 1;
                                if(v3d->gpd) {
                                        v3d->gpd= newdataadr(fd, v3d->gpd);
-                                       link_gpencil(fd, v3d->gpd);
+                                       direct_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;
+                       else if (sl->spacetype==SPACE_IPO) {
+                               SpaceIpo *sipo= (SpaceIpo*)sl;
                                
-                               link_list(fd, &(soops->oops));
-                               oops= soops->oops.first;
-                               while(oops) {
-                                       oops->link.first= oops->link.last= 0;
-                                       oops= oops->next;
-                               }
+                               sipo->ads= newdataadr(fd, sipo->ads);
+                               sipo->ghostCurves.first= sipo->ghostCurves.last= NULL;
+                       }
+                       else if (sl->spacetype==SPACE_OUTLINER) {
+                               SpaceOops *soops= (SpaceOops*) sl;
                                
                                soops->treestore= newdataadr(fd, soops->treestore);
                                if(soops->treestore) {
@@ -4284,11 +4716,12 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                SpaceImage *sima= (SpaceImage *)sl;
                                
                                sima->cumap= newdataadr(fd, sima->cumap);
-                               if(sima->cumap)
-                                       direct_link_curvemapping(fd, sima->cumap);
                                sima->gpd= newdataadr(fd, sima->gpd);
                                if (sima->gpd)
-                                       link_gpencil(fd, sima->gpd);
+                                       direct_link_gpencil(fd, sima->gpd);
+                               if(sima->cumap)
+                                       direct_link_curvemapping(fd, sima->cumap);
+                               sima->iuser.scene= NULL;
                                sima->iuser.ok= 1;
                        }
                        else if(sl->spacetype==SPACE_NODE) {
@@ -4296,33 +4729,40 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                
                                if(snode->gpd) {
                                        snode->gpd= newdataadr(fd, snode->gpd);
-                                       link_gpencil(fd, snode->gpd);
+                                       direct_link_gpencil(fd, snode->gpd);
                                }
                                snode->nodetree= snode->edittree= NULL;
-                               snode->flag |= SNODE_DO_PREVIEW;
+                       }
+                       else if(sl->spacetype==SPACE_LOGIC) {
+                               SpaceLogic *slogic= (SpaceLogic *)sl;
+                               
+                               if(slogic->gpd) {
+                                       slogic->gpd= newdataadr(fd, slogic->gpd);
+                                       direct_link_gpencil(fd, slogic->gpd);
+                               }
                        }
                        else if(sl->spacetype==SPACE_SEQ) {
                                SpaceSeq *sseq= (SpaceSeq *)sl;
                                if(sseq->gpd) {
                                        sseq->gpd= newdataadr(fd, sseq->gpd);
-                                       link_gpencil(fd, sseq->gpd);
+                                       direct_link_gpencil(fd, sseq->gpd);
                                }
                        }
+                       else if(sl->spacetype==SPACE_BUTS) {
+                               SpaceButs *sbuts= (SpaceButs *)sl;
+                               sbuts->path= NULL;
+                       }
                }
+               
+               sa->actionzones.first= sa->actionzones.last= NULL;
 
                sa->v1= newdataadr(fd, sa->v1);
                sa->v2= newdataadr(fd, sa->v2);
                sa->v3= newdataadr(fd, sa->v3);
                sa->v4= newdataadr(fd, sa->v4);
 
-               sa->win= sa->headwin= 0;
-
-               sa->uiblocks.first= sa->uiblocks.last= NULL;
-
                /* space handler scriptlinks */
                direct_link_scriptlink(fd, &sa->scriptlink);
-
-               sa= sa->next;
        }
 }
 
@@ -4344,7 +4784,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
                                BLI_remlink(&main->library, lib);
                                MEM_freeN(lib);
                                
-                               error("Library had multiple instances, save and reload!");
+                               BKE_report(fd->reports, RPT_WARNING, "Library had multiple instances, save and reload!");
+
                                return;
                        }
                }
@@ -4409,7 +4850,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;
@@ -4485,6 +4926,7 @@ static char *dataname(short id_code)
                case ID_NT: return "Data from NT";
                case ID_BR: return "Data from BR";
                case ID_PA: return "Data from PA";
+               case ID_GD: return "Data from GD";
        }
        return "Data from Lib Block";
        
@@ -4537,9 +4979,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);
                }
@@ -4549,6 +5002,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
 
        /* init pointers direct data */
        switch( GS(id->name) ) {
+               case ID_WM:
+                       direct_link_windowmanager(fd, (wmWindowManager *)id);
+                       break;
                case ID_SCR:
                        direct_link_screen(fd, (bScreen *)id);
                        break;
@@ -4627,6 +5083,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                case ID_SCRIPT:
                        direct_link_script(fd, (Script*)id);
                        break;
+               case ID_GD:
+                       direct_link_gpencil(fd, (bGPdata *)id);
+                       break;
        }
        
        /*link direct data of ID properties*/
@@ -4643,16 +5102,36 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        return (bhead);
 }
 
-static void link_global(FileData *fd, BlendFileData *bfd, FileGlobal *fg)
+/* note, this has to be kept for reading older files... */
+/* also version info is written here */
+static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
 {
-       // this is nonsense... make it struct once (ton)
+       FileGlobal *fg= read_struct(fd, bhead, "Global");
+       
+       /* copy to bfd handle */
+       bfd->main->subversionfile= fg->subversion;
+       bfd->main->minversionfile= fg->minversion;
+       bfd->main->minsubversionfile= fg->minsubversion;
+       
        bfd->winpos= fg->winpos;
        bfd->fileflags= fg->fileflags;
        bfd->displaymode= fg->displaymode;
        bfd->globalf= fg->globalf;
        
-       bfd->curscreen= newlibadr(fd, 0, fg->curscreen);
-       bfd->curscene= newlibadr(fd, 0, fg->curscene);
+       bfd->curscreen= fg->curscreen;
+       bfd->curscene= fg->curscene;
+       
+       MEM_freeN(fg);
+       
+       return blo_nextbhead(fd, bhead);
+}
+
+/* note, this has to be kept for reading older files... */
+static void link_global(FileData *fd, BlendFileData *bfd)
+{
+       
+       bfd->curscreen= newlibadr(fd, 0, bfd->curscreen);
+       bfd->curscene= newlibadr(fd, 0, bfd->curscene);
        // this happens in files older than 2.35
        if(bfd->curscene==NULL) {
                if(bfd->curscreen) bfd->curscene= bfd->curscreen->scene;
@@ -4685,19 +5164,19 @@ static void vcol_to_fcol(Mesh *me)
 static int map_223_keybd_code_to_224_keybd_code(int code)
 {
        switch (code) {
-       case 312:       return F12KEY;
-       case 159:       return PADSLASHKEY;
-       case 161:       return PAD0;
-       case 154:       return PAD1;
-       case 150:       return PAD2;
-       case 155:       return PAD3;
-       case 151:       return PAD4;
-       case 156:       return PAD5;
-       case 152:       return PAD6;
-       case 157:       return PAD7;
-       case 153:       return PAD8;
-       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;
        }
 }
 
@@ -5011,7 +5490,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
        /* 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[mf->mat_nr]);
+                       ma= newlibadr(fd, lib, me->mat[(int)mf->mat_nr]);
                        texalpha = 0;
 
                        /* we can't read from this if it comes from a library,
@@ -5024,24 +5503,358 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
                                if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
                                        texalpha = 1;
                }
-               else {
-                       ma= NULL;
-                       texalpha = 0;
+               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;
+                               /* temporarily hide it */
+                               ar->flag = RGN_FLAG_HIDDEN;
+                               break;
+                               
+                       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;
+
+#if 0
+                       case SPACE_BUTS:
+                               /* context UI region */
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_CHANNELS;
+                               ar->alignment= RGN_ALIGN_TOP;
+                               break;
+#endif
+               }
+       }
+
+       /* 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_OUTLINER:
+                       {
+                               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;
+                       }
+                               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));
+                               
+                               /* init mainarea 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 > 120)? (sa->winx) : 120);
+                               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));
+                               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_TEXT:
+                       {
+                               SpaceText *st= (SpaceText *)sl;
+                               st->flags |= ST_FIND_WRAP;
+                       }
+                               //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)
+{
+       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)
+                       area_add_header_region(sa, &sa->regionbase);
+               
+               area_add_window_regions(sa, sa->spacedata.first, &sa->regionbase);
+               
+               /* 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);
+                       }
                }
+       }
+}
 
-               for(b=0; b<me->fdata.totlayer; b++) {
-                       if(me->fdata.layers[b].type == CD_MTFACE) {
-                               tf = ((MTFace*)me->fdata.layers[b].data) + a;
+static void versions_gpencil_add_main(ListBase *lb, ID *id, char *name)
+{
+       
+       BLI_addtail(lb, id);
+       id->us= 1;
+       id->flag= LIB_FAKEUSER;
+       *( (short *)id->name )= ID_GD;
+       
+       new_id(lb, id, name);
+       /* alphabetic insterion: is in new_id */
+       
+       if(G.f & G_DEBUG)
+               printf("Converted GPencil to ID: %s\n", id->name+2);
+}
 
-                               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;
+static void do_versions_gpencil_2_50(Main *main, bScreen *screen)
+{
+       ScrArea *sa;
+       SpaceLink *sl;
+       
+       /* add regions */
+       for(sa= screen->areabase.first; sa; sa= sa->next) {
+               for(sl= sa->spacedata.first; sl; sl= sl->next) {
+                       if (sl->spacetype==SPACE_VIEW3D) {
+                               View3D *v3d= (View3D*) sl;
+                               if(v3d->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)v3d->gpd, "GPencil View3D");
+                                       v3d->gpd= NULL;
+                               }
+                       }
+                       else if (sl->spacetype==SPACE_NODE) {
+                               SpaceNode *snode= (SpaceNode *)sl;
+                               if(snode->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)snode->gpd, "GPencil Node");
+                                       snode->gpd= NULL;
+                               }
+                       }
+                       else if (sl->spacetype==SPACE_SEQ) {
+                               SpaceSeq *sseq= (SpaceSeq *)sl;
+                               if(sseq->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)sseq->gpd, "GPencil Node");
+                                       sseq->gpd= NULL;
+                               }
+                       }
+                       else if (sl->spacetype==SPACE_IMAGE) {
+                               SpaceImage *sima= (SpaceImage *)sl;
+                               if(sima->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)sima->gpd, "GPencil Image");
+                                       sima->gpd= NULL;
+                               }
                        }
                }
-       }
+       }               
 }
 
+
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -5314,10 +6127,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                while(sl) {
                                        if(sl->spacetype==SPACE_TEXT) {
                                                SpaceText *st= (SpaceText*) sl;
-                                               if(st->font_id>1) {
-                                                       st->font_id= 0;
-                                                       st->lheight= 13;
-                                               }
+                                               st->lheight= 12;
                                        }
                                        sl= sl->next;
                                }
@@ -5648,8 +6458,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;
                                }
 
@@ -6019,29 +6829,29 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                                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;
+                                                       //sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_LAMP;
                                                }
                                                else if(sbuts->mainb==BUTS_MAT) {
                                                        sbuts->mainb= CONTEXT_SHADING;
-                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
+                                                       //sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT;
                                                }
                                                else if(sbuts->mainb==BUTS_TEX) {
                                                        sbuts->mainb= CONTEXT_SHADING;
-                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_TEX;
+                                                       //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;
+                                                       //sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_WORLD;
                                                }
                                                else if(sbuts->mainb==BUTS_RENDER) {
                                                        sbuts->mainb= CONTEXT_SCENE;
-                                                       sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_RENDER;
+                                                       //sbuts->tab[CONTEXT_SCENE]= TAB_SCENE_RENDER;
                                                }
                                                else if(sbuts->mainb==BUTS_GAME) {
                                                        sbuts->mainb= CONTEXT_LOGIC;
@@ -6051,7 +6861,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                }
                                                else if(sbuts->mainb==BUTS_RADIO) {
                                                        sbuts->mainb= CONTEXT_SHADING;
-                                                       sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_RAD;
+                                                       //sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_RAD;
                                                }
                                                else if(sbuts->mainb==BUTS_CONSTRAINT) {
                                                        sbuts->mainb= CONTEXT_OBJECT;
@@ -6332,10 +7142,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                while(sce) {
                        ed= sce->ed;
                        if(ed) {
-                               WHILE_SEQ(&ed->seqbase) {
-                                       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;
@@ -6372,12 +7183,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                View3D *v3d= (View3D *)sl;
                                                if(v3d->twtype==0) v3d->twtype= V3D_MANIP_TRANSLATE;
                                        }
-#ifndef SHOWDEPGRAPH
-                                       else if(sl->spacetype==SPACE_OOPS) {
-                                               if ( ((SpaceOops *)sl)->type==SO_DEPSGRAPH)
-                                                        ((SpaceOops *)sl)->type=SO_OOPS;
-                                       }
-#endif                         
                                        else if(sl->spacetype==SPACE_TIME) {
                                                SpaceTime *stime= (SpaceTime *)sl;
                                                if(stime->redraws==0)
@@ -7059,7 +7864,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) {
@@ -7184,7 +7989,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;
                        }
                }
        }
@@ -7291,14 +8096,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;
@@ -7308,8 +8113,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;
@@ -7378,11 +8182,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;
                        }
 
@@ -7499,9 +8303,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 */
                }
        }
 
@@ -7684,7 +8488,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                                part->draw_as = PART_DRAW_PATH;
                                                part->type = PART_HAIR;
-                                               psys->recalc |= PSYS_RECALC_HAIR;
+                                               psys->recalc |= PSYS_RECALC_REDO;
 
                                                part->normfac *= fac;
                                                part->randfac *= fac;
@@ -7810,22 +8614,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        }
 
        if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 14)) {
-               Scene *sce= main->scene.first;
+               Scene *sce;
                Sequence *seq;
-               Editing *ed;
                
-               while(sce) {
-                       ed= sce->ed;
-                       if(ed) {
-                               WHILE_SEQ(&ed->seqbase) {
-                                       if (seq->blend_mode == 0) {
-                                               seq->blend_opacity = 100.0;
-                                       }
-                               }
-                               END_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;
                        }
-                       
-                       sce= sce->id.next;
+                       SEQ_END
                }
        }
        
@@ -7914,7 +8711,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                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.0;
+                               ob->pd->f_noise = 0.0f;
                }
        }
 
@@ -7922,7 +8719,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Object *ob;
                for(ob = main->object.first; ob; ob= ob->id.next) {
                        ob->gameflag |= OB_COLLISION;
-                       ob->margin = 0.06;
+                       ob->margin = 0.06f;
                }
        }
 
@@ -8035,20 +8832,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                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.0;
-                               la->spread = 1.0;
-                               la->sun_brightness = 1.0;
-                               la->sun_size = 1.0;
-                               la->backscattered_light = 1.0;
-                               la->atm_turbidity = 2.0;
-                               la->atm_inscattering_factor = 1.0;
-                               la->atm_extinction_factor = 1.0;
-                               la->atm_distance_factor = 1.0;
-                               la->sun_intensity = 1.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;
                
@@ -8083,6 +8880,43 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        sce->toolsettings->skgen_retarget_roll = SK_RETARGET_ROLL_VIEW;
                }
        }
+       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 < 248 || (main->versionfile == 248 && main->subversionfile < 3)) {
                Object *ob;
@@ -8155,6 +8989,153 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        
        }
+
+       if (main->versionfile < 250) {
+               bScreen *screen;
+               Scene *scene;
+               Material *ma;
+               Mesh *me;
+               Scene *sce;
+               Tex *tx;
+               ParticleSettings *part;
+               
+               for(screen= main->screen.first; screen; screen= screen->id.next) {
+                       do_versions_windowmanager_2_50(screen);
+                       do_versions_gpencil_2_50(main, 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");
+               }
+               
+               /* copy standard draw flag to meshes(used to be global, is not available here) */
+               for(me= main->mesh.first; me; me= me->id.next) {
+                       me->drawflag= ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
+               }
+
+               /* particle settings conversion */
+               for(part= main->particle.first; part; part= part->id.next) {
+                       if(part->draw_as) {
+                               if(part->draw_as == PART_DRAW_DOT) {
+                                       part->ren_as = PART_DRAW_HALO;
+                                       part->draw_as = PART_DRAW_REND;
+                               }
+                               else if(part->draw_as <= PART_DRAW_AXIS) {
+                                       part->ren_as = PART_DRAW_HALO;
+                               }
+                               else {
+                                       part->ren_as = part->draw_as;
+                                       part->draw_as = PART_DRAW_REND;
+                               }
+                       }
+               }
+       }
+
+       /* 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;
+               Material *ma;
+               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_mark_as_modified(dm);
+                                       dm->release(dm);
+                                       orig->release(orig);
+
+                                       /* Remove the old multires */
+                                       multires_free(me->mr);
+                                       me->mr = NULL;
+                               }
+
+                               ob->data = olddata;
+                       }
+               }
+
+               for(ma = main->mat.first; ma; ma = ma->id.next) {
+                       if(ma->mode & MA_HALO) {
+                               ma->material_type= MA_TYPE_HALO;
+                               ma->mode &= ~MA_HALO;
+                       }
+               }
+       }
        
        if (main->versionfile < 249 && main->subversionfile < 2) {
                Scene *sce= main->scene.first;
@@ -8164,9 +9145,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                while(sce) {
                        ed= sce->ed;
                        if(ed) {
-                               WHILE_SEQ(&ed->seqbase) {
+                               SEQP_BEGIN(ed, seq) {
                                        if (seq->strip && seq->strip->proxy){
-                                               if (G.scene->r.size != 100.0) {
+                                               if (sce->r.size != 100.0) {
                                                        seq->strip->proxy->size
                                                                = sce->r.size;
                                                } else {
@@ -8176,7 +9157,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                seq->strip->proxy->quality =90;
                                        }
                                }
-                               END_SEQ
+                               SEQ_END
                        }
                        
                        sce= sce->id.next;
@@ -8195,6 +9176,7 @@ static void lib_link_all(FileData *fd, Main *main)
 {
        oldnewmap_sort(fd);
        
+       lib_link_windowmanager(fd, main);
        lib_link_screen(fd, main);
        lib_link_scene(fd, main);
        lib_link_object(fd, main);
@@ -8203,7 +9185,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);
@@ -8215,7 +9197,6 @@ static void lib_link_all(FileData *fd, Main *main)
        lib_link_armature(fd, main);
        lib_link_action(fd, main);
        lib_link_vfont(fd, main);
-       lib_link_screen_sequence_ipos(main);
        lib_link_nodetree(fd, main);    /* has to be done after scene/materials, this will verify group nodes */
        lib_link_brush(fd, main);
        lib_link_particlesettings(fd, main);
@@ -8225,13 +9206,17 @@ static void lib_link_all(FileData *fd, Main *main)
        lib_link_library(fd, main);             /* only init users */
 }
 
+
 static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
 {
        Link *link;
 
        bfd->user= read_struct(fd, bhead, "user def");
        bfd->user->themes.first= bfd->user->themes.last= NULL;
-
+       // XXX
+       bfd->user->uifonts.first= bfd->user->uifonts.last= NULL;
+       bfd->user->uistyles.first= bfd->user->uistyles.last= NULL;
+       
        bhead = blo_nextbhead(fd, bhead);
 
                /* read all attached data */
@@ -8244,11 +9229,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");
@@ -8258,20 +9242,15 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
        
        while(bhead) {
                switch(bhead->code) {
-               case GLOB:
                case DATA:
                case DNA1:
                case TEST:
                case REND:
-                       if (bhead->code==GLOB) {
-                               fg= read_struct(fd, bhead, "Global");
-                               /* set right away */
-                               bfd->main->subversionfile= fg->subversion;
-                               bfd->main->minversionfile= fg->minversion;
-                               bfd->main->minsubversionfile= fg->minsubversion;
-                       }
                        bhead = blo_nextbhead(fd, bhead);
                        break;
+               case GLOB:
+                       bhead= read_global(bfd, fd, bhead);
+                       break;
                case USER:
                        bhead= read_userdef(bfd, fd, bhead);
                        break;
@@ -8290,6 +9269,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);
                }
@@ -8307,11 +9290,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
        lib_verify_nodetree(bfd->main, 1);
        fix_relpaths_library(fd->filename, bfd->main); /* make all relative paths, relative to the open blend file */
        
-       if(fg)
-               link_global(fd, bfd, fg);       /* as last */
-
-       /* removed here: check for existance of curscreen/scene, moved to kernel setup_app */
-       MEM_freeN(fg);
+       link_global(fd, bfd);   /* as last */
        
        return bfd;
 }
@@ -8470,14 +9449,9 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
        }
 }
 
-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);
-}
 
+
+// XXX depreceated - old animation system
 static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
 {
        IpoCurve *icu;
@@ -8487,6 +9461,64 @@ 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_keyingsets(FileData *fd, Main *mainvar, ListBase *list)
+{
+       KeyingSet *ks;
+       KS_Path *ksp;
+       
+       /* expand the ID-pointers in KeyingSets's paths */
+       for (ks= list->first; ks; ks= ks->next) {
+               for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+                       expand_doit(fd, mainvar, ksp->id);
+               }
+       }
+}
+
+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;
+               DriverTarget *dtar;
+               
+               for (dtar= driver->targets.first; dtar; dtar= dtar->next)
+                       expand_doit(fd, mainvar, dtar->id);
+       }
+}      
+
+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;
@@ -8498,13 +9530,19 @@ 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;
        
+       if(ntree->adt)
+               expand_animdata(fd, mainvar, ntree->adt);
+       
        for(node= ntree->nodes.first; node; node= node->next)
                if(node->id && node->type!=CMP_NODE_R_LAYERS)
                        expand_doit(fd, mainvar, node->id);
@@ -8514,7 +9552,10 @@ static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
 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);
@@ -8541,7 +9582,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);
@@ -8557,12 +9601,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);
 }
 
@@ -8577,7 +9625,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);
 }
 
 
@@ -8597,15 +9649,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)
@@ -8648,7 +9704,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:
@@ -8800,23 +9856,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) {
@@ -8870,16 +9909,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);
-       expand_doit(fd, mainvar, ob->poselib);
-
+       
        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){
@@ -8887,7 +9929,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]);
        }
@@ -8991,6 +10037,10 @@ 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);
+       expand_keyingsets(fd, mainvar, &sce->keyingsets);
+       
        if(sce->set)
                expand_doit(fd, mainvar, sce->set);
        
@@ -9008,12 +10058,15 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
 
 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
 }
 
 
@@ -9080,7 +10133,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);
@@ -9092,7 +10145,7 @@ 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);
@@ -9108,24 +10161,24 @@ 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, int is_group_append)
+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 ) {
                        
@@ -9141,7 +10194,7 @@ static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib, int is_
                                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(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0)
                                                do_it= 1;
                                                
                                if(do_it) {
@@ -9198,11 +10251,10 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                        if(id==NULL) ob= mainvar->object.last;
                                        else ob= (Object *)id;
                                        
-                                       /* this is bad code... G.vd nor G.scene should be used on this level... */
-                                       if((flag & FILE_ACTIVELAY)) {
-                                               if(G.vd) ob->lay= G.vd->layact;
-                                               else ob->lay = G.scene->lay;
-                                       }
+                                       /* XXX use context to find view3d->lay */
+                                       //if((flag & FILE_ACTIVELAY)) {
+                                       //      scene->lay;
+                                       //}
                                        base->lay= ob->lay;
                                        base->object= ob;
                                        ob->id.us++;
@@ -9243,14 +10295,14 @@ 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,
+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);
@@ -9287,21 +10339,21 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
        }
 
        blo_join_main(&(*fd)->mainlist);
-       G.main= (*fd)->mainlist.first;
+       mainvar= (*fd)->mainlist.first;
 
-       lib_link_all(*fd, G.main);
-       lib_verify_nodetree(G.main, 0);
-       fix_relpaths_library(G.sce, G.main); /* make all relative paths, relative to the open blend file */
+       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) {
                if (flag & FILE_LINK) {
-                       give_base_to_objects(scene, &(G.main->object), NULL, 0);
+                       give_base_to_objects(mainvar, scene, NULL, 0);
                } else {
-                       give_base_to_objects(scene, &(G.main->object), curlib, 1);
+                       give_base_to_objects(mainvar, scene, curlib, 1);
                }       
        } else {
-               give_base_to_objects(scene, &(G.main->object), NULL, 0);
+               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 */
@@ -9318,30 +10370,30 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
 
 /* this is a version of BLO_library_append needed by the BPython API, so
  * scripts can load data from .blend files -- see Blender.Library module.*/
-/* append to G.scene */
+/* 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 )
+               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(G.scene);
-}
+       DAG_scene_sort(scene);
 
-/* append to G.scene */
-/* dir is a full path */       
-void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
-{
-       BLO_library_append_(&sfile->libfiledata, sfile->filelist, sfile->totfile, dir, sfile->file, sfile->flag, idcode);
-       BLO_blendhandle_close(sfile->libfiledata);
-       sfile->libfiledata= NULL;
+       *bh= (BlendHandle*)fd;
 }
 
-void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode)
+/* 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*)(*bh);
        Library *curlib;
        Base *centerbase;
        Object *ob;
@@ -9361,20 +10413,24 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
                                if( strcmp(filelist[a].relname, file)==0) break;
                        }
                        if(a==totfile) {
-                               error("Wrong indicated name");
+                               BKE_report(reports, RPT_ERROR, "Wrong indicated name");
                                return;
                        }
                }
                else {
-                       error("Nothing indicated");
+                       BKE_report(reports, RPT_ERROR, "Nothing indicated");
                        return;
                }
        }
        /* now we have or selected, or an indicated file */
        
-       if(flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
+       if(flag & FILE_AUTOSELECT) scene_deselect_all(scene);
+
+       fd->reports= reports;
+       curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag );
+       if(fd) fd->reports= NULL;
 
-       curlib = library_append( G.scene, file, dir, idcode, totsel, (FileData**) libfiledata, filelist, totfile,flag );
+       *bh= (BlendHandle*)fd;
 
        /* when not linking (appending)... */
        if((flag & FILE_LINK)==0) {
@@ -9384,7 +10440,7 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
                        
                        INIT_MINMAX(min, max);
                        
-                       centerbase= (G.scene->base.first);
+                       centerbase= (scene->base.first);
                        while(centerbase) {
                                if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
                                        VECCOPY(vec, centerbase->object->loc);
@@ -9397,10 +10453,10 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
                                centerloc[0]= (min[0]+max[0])/2;
                                centerloc[1]= (min[1]+max[1])/2;
                                centerloc[2]= (min[2]+max[2])/2;
-                               curs = G.scene->cursor;
+                               curs = scene->cursor;
                                VECSUB(centerloc,curs,centerloc);
                        
-                               centerbase= (G.scene->base.first);
+                               centerbase= (scene->base.first);
                                while(centerbase) {
                                        if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
                                                ob= centerbase->object;
@@ -9453,9 +10509,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);
@@ -9554,7 +10613,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
 
 /* reading runtime */
 
-BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize, BlendReadError *error_r) 
+BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize, ReportList *reports)
 {
        BlendFileData *bfd = NULL;
        FileData *fd = filedata_new();
@@ -9565,11 +10624,12 @@ BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize,
        /* needed for library_append and read_libraries */
        BLI_strncpy(fd->filename, name, sizeof(fd->filename));
 
-       fd = blo_decode_and_check(fd, error_r);
+       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;