diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c
index 208b2df..444d491 100644
--- a/apps/gui/bitmap/list-skinned.c
+++ b/apps/gui/bitmap/list-skinned.c
@@ -175,22 +175,23 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
     for (cur_line = 0; cur_line < display_lines; cur_line++)
     {
         struct skin_element* viewport;
-        struct skin_viewport* skin_viewport;
+        struct skin_viewport* skin_viewport = NULL;
         if (list_start_item+cur_line+1 > list->nb_items)
             break;
         current_drawing_line = list_start_item+cur_line;
         is_selected = list->show_selection_marker &&
                 list_start_item+cur_line == list->selected_item;
         
-        for (viewport = listcfg[screen]->data->tree;
+        for (viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->data->tree);
              viewport;
-             viewport = viewport->next)
+             viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->next))
         {
             int origional_x, origional_y;
             int origional_w, origional_h;
+            char *viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label);
             skin_viewport = (struct skin_viewport*)viewport->data;
-            if (viewport->children == 0 || !skin_viewport->label ||
-                (skin_viewport->label && strcmp(label, skin_viewport->label))
+            if (viewport->children == 0 || !viewport_label ||
+                (skin_viewport->label && strcmp(label, viewport_label))
                 )
                 continue;
             if (is_selected)
@@ -220,15 +221,17 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
             display->set_viewport(&skin_viewport->vp);
 #ifdef HAVE_LCD_BITMAP
             /* Set images to not to be displayed */
-            struct skin_token_list *imglist = wps.data->images;
+            struct skin_token_list *imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), wps.data->images);
             while (imglist)
             {
-                struct gui_img *img = (struct gui_img *)imglist->token->value.data;
+                struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token);
+                struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data);
                 img->display = -1;
-                imglist = imglist->next;
+                imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next);
             }
 #endif
-            skin_render_viewport(viewport->children[0],
+            struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children);
+            skin_render_viewport(children[0],
                                  &wps, skin_viewport, SKIN_REFRESH_ALL);
 #ifdef HAVE_LCD_BITMAP
             wps_display_images(&wps, &skin_viewport->vp);
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index d2dbb56..1114c09 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -102,7 +102,7 @@ void skin_statusbar_changed(struct gui_wps *skin)
     struct wps_data *data = skin->data;
     const struct screen *display = skin->display;
     const int   screen = display->screen_type;
-    struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data);
+    struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
 
     struct viewport *vp = &svp->vp;
     viewport_set_defaults(vp, screen);
@@ -131,7 +131,7 @@ void skin_statusbar_changed(struct gui_wps *skin)
 void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
 {
     struct screen *display = gwps->display;
-    struct viewport *vp = pb->vp;
+    struct viewport *vp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->vp);
     struct wps_state *state = skin_get_global_state();
     struct mp3entry *id3 = state->id3;
     int x = pb->x, y = pb->y, width = pb->width, height = pb->height;
@@ -226,9 +226,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
         flags |= INNER_NOFILL;
     }
 
-    if (pb->slider)
+    if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider))
     {
-        struct gui_img *img = pb->slider;
+        struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider);
         /* clear the slider */
         screen_clear_area(display, x, y, width, height);
 
@@ -245,9 +245,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
         }
     }
     
-    if (pb->backdrop)
+    if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop))
     {
-        struct gui_img *img = pb->backdrop;
+        struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop);
         img->bm.data = core_get_data(img->buflib_handle);
         display->bmp_part(&img->bm, 0, 0, x, y, width, height);
         flags |= DONT_CLEAR_EXCESS;
@@ -255,11 +255,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
     
     if (!pb->nobar)
     {
-        if (pb->image)
+        struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->image);
+        if (img)
         {
-            char *img_data = core_get_data(pb->image->buflib_handle);
-            pb->image->bm.data = img_data;
-            gui_bitmap_scrollbar_draw(display, &pb->image->bm,
+            char *img_data = core_get_data(img->buflib_handle);
+            img->bm.data = img_data;
+            gui_bitmap_scrollbar_draw(display, &img->bm,
                                     x, y, width, height,
                                     length, 0, end, flags);
         }
@@ -268,11 +269,11 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
                                length, 0, end, flags);
     }
 
-    if (pb->slider)
+    if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider))
     {
         int xoff = 0, yoff = 0;
         int w = width, h = height;
-        struct gui_img *img = pb->slider;
+        struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider);
         img->bm.data = core_get_data(img->buflib_handle);
 
         if (flags&HORIZONTAL)
@@ -347,11 +348,12 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
 
     struct wps_data *data = gwps->data;
     struct screen *display = gwps->display;
-    struct skin_token_list *list = data->images;
+    struct skin_token_list *list = SKINOFFSETTOPTR(get_skin_buffer(data), data->images);
 
     while (list)
     {
-        struct gui_img *img = (struct gui_img*)list->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token);
+        struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
         if (img->using_preloaded_icons && img->display >= 0)
         {
             screen_put_icon(display, img->x, img->y, img->display);
@@ -362,20 +364,21 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
             {
                 wps_draw_image(gwps, img, img->display);
             }
-            else if (img->always_display && img->vp == vp)
+            else if (img->always_display && SKINOFFSETTOPTR(get_skin_buffer(data), img->vp) == vp)
             {
                 wps_draw_image(gwps, img, 0);
             }
         }
-        list = list->next;
+        list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);
     }
 #ifdef HAVE_ALBUMART
     /* now draw the AA */
-    if (data->albumart && data->albumart->vp == vp
-        && data->albumart->draw_handle >= 0)
+    struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
+    if (aa && SKINOFFSETTOPTR(get_skin_buffer(data), aa->vp) == vp
+        && aa->draw_handle >= 0)
     {
-        draw_album_art(gwps, data->albumart->draw_handle, false);
-        data->albumart->draw_handle = -1;
+        draw_album_art(gwps, aa->draw_handle, false);
+        aa->draw_handle = -1;
     }
 #endif
 
@@ -398,8 +401,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
 
     int intval = num_options < 2 ? 2 : num_options;
     /* get_token_value needs to know the number of options in the enum */
-    value = get_token_value(gwps, conditional->token, offset,
-                            result, sizeof(result), &intval);
+    value = get_token_value(gwps, SKINOFFSETTOPTR(get_skin_buffer(gwps->data), conditional->token),
+                    offset, result, sizeof(result), &intval);
 
     /* intval is now the number of the enum option we want to read,
        starting from 1. If intval is -1, we check if value is empty. */
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index bd875fe..75862fa 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -41,19 +41,10 @@
 static bool skins_initialising = true;
 
 /* App uses the host malloc to manage the buffer */
-#ifdef APPLICATION
-#define skin_buffer NULL
 void theme_init_buffer(void)
 {
     skins_initialising = false;
 }
-#else
-static char skin_buffer[SKIN_BUFFER_SIZE];
-void theme_init_buffer(void)
-{
-    skins_initialising = false;
-}
-#endif
 
 void skin_data_free_buflib_allocs(struct wps_data *wps_data);
 char* wps_default_skin(enum screen_type screen);
@@ -95,8 +86,20 @@ void gui_sync_skin_init(void)
             skins[j][i].gui_wps.display = &screens[i];
             memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data));
             skins[j][i].data.wps_loaded = false;
+            skins[j][i].data.buflib_handle = -1;
+            skins[j][i].data.tree = -1;
+#ifdef HAVE_TOUCHSCREEN
+            skins[j][i].data.touchregions = -1;
+#endif
+#ifdef HAVE_SKIN_VARIABLES
+            skins[j][i].data.skinvars = -1;
+#endif
+#ifdef HAVE_LCD_BITMAP
+            skins[j][i].data.font_ids = -1;
+            skins[j][i].data.images = -1;
+#endif
 #ifdef HAVE_ALBUMART
-            skins[j][i].data.albumart = NULL;
+            skins[j][i].data.albumart = -1;
             skins[j][i].data.playback_aa_slot = -1;
 #endif
         }
@@ -113,8 +116,6 @@ void skin_unload_all(void)
             skin_data_free_buflib_allocs(&skins[j][i].data);
     }
 
-    skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
-
 #ifdef HAVE_LCD_BITMAP
     skin_backdrop_init();
 #endif
@@ -245,7 +246,6 @@ struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type scre
         cpu_boost(false);
         loading_a_sbs = false;
     }
-        
     return &skins[skin][screen].gui_wps;
 }
 
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 8eef1de..e194b46 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -73,16 +73,46 @@
 
 #include "backdrop.h"
 #include "statusbar-skinned.h"
+#include "core_alloc.h"
 
 #define WPS_ERROR_INVALID_PARAM         -1
 
 #define GLYPHS_TO_CACHE 256
+static char* skin_buffer = NULL;
+void skinparser_set_buffer(char* pointer)
+{
+    skin_buffer = pointer;
+}
+
+#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
+static char *backdrop_filename;
+#endif
 
 static bool isdefault(struct skin_tag_parameter *param)
 {
     return param->type == DEFAULT;
 }
 
+static inline char*
+get_param_text(struct skin_element *element, int param_number)
+{
+    struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
+    return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.text);
+}
+
+static inline struct skin_element*
+get_param_code(struct skin_element *element, int param_number)
+{
+    struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
+    return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.code);
+}
+
+static inline struct skin_tag_parameter*
+get_param(struct skin_element *element, int param_number)
+{
+    struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
+    return &params[param_number];
+}
 
 /* which screen are we parsing for? */
 static enum screen_type curr_screen;
@@ -90,6 +120,7 @@ static enum screen_type curr_screen;
 /* the current viewport */
 static struct skin_element *curr_viewport_element;
 static struct skin_viewport *curr_vp;
+static struct skin_element *first_viewport;
 
 static struct line *curr_line;
 
@@ -103,16 +134,18 @@ typedef int (*parse_function)(struct skin_element *element,
 /* add a skin_token_list item to the list chain. ALWAYS appended because some of the
  * chains require the order to be kept.
  */
-static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_list *item)
+static void add_to_ll_chain(skinoffset *listoffset, struct skin_token_list *item)
 {
-    if (*list == NULL)
-        *list = item;
+    struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, *listoffset);
+    if (list == NULL)
+    {
+        *listoffset = PTRTOSKINOFFSET(skin_buffer, item);
+    }
     else
     {
-        struct skin_token_list *t = *list;
-        while (t->next)
-            t = t->next;
-        t->next = item;
+        while (SKINOFFSETTOPTR(skin_buffer, list->next))
+            list = SKINOFFSETTOPTR(skin_buffer, list->next);
+        list->next = PTRTOSKINOFFSET(skin_buffer, item);
     }
 }
 
@@ -123,32 +156,36 @@ void *skin_find_item(const char *label, enum skin_find_what what,
                      struct wps_data *data)
 {
     const char *itemlabel = NULL;
+    char *old_skin_buffer = skin_buffer;
+    char *databuf = get_skin_buffer(data);
     union {
         struct skin_token_list *linkedlist;
         struct skin_element *vplist;
     } list = {NULL};
     bool isvplist = false;
     void *ret = NULL;
+    if (databuf && databuf != skin_buffer)
+        skin_buffer = get_skin_buffer(data);
     switch (what)
     {
         case SKIN_FIND_UIVP:
         case SKIN_FIND_VP:
-            list.vplist = data->tree;
+            list.vplist = SKINOFFSETTOPTR(skin_buffer, data->tree);
             isvplist = true;
         break;
 #ifdef HAVE_LCD_BITMAP
         case SKIN_FIND_IMAGE:
-            list.linkedlist = data->images;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->images);
         break;
 #endif
 #ifdef HAVE_TOUCHSCREEN
         case SKIN_FIND_TOUCHREGION:
-            list.linkedlist = data->touchregions;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
         break;
 #endif
 #ifdef HAVE_SKIN_VARIABLES
         case SKIN_VARIABLE:
-            list.linkedlist = data->skinvars;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->skinvars);
         break;
 #endif
     }
@@ -156,43 +193,55 @@ void *skin_find_item(const char *label, enum skin_find_what what,
     while (list.linkedlist)
     {
         bool skip = false;
+        struct wps_token *token = NULL;
+        if (!isvplist)
+            token = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->token);
         switch (what)
         {
             case SKIN_FIND_UIVP:
             case SKIN_FIND_VP:
-                ret = list.vplist->data;
-                itemlabel = ((struct skin_viewport *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, list.vplist->data);
+                if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL)
+                    itemlabel = VP_DEFAULT_LABEL_STRING;
+                else
+                    itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_viewport *)ret)->label);
                 skip = !(((struct skin_viewport *)ret)->is_infovp == 
                     (what==SKIN_FIND_UIVP));
                 break;
 #ifdef HAVE_LCD_BITMAP
             case SKIN_FIND_IMAGE:
-                ret = list.linkedlist->token->value.data;
-                itemlabel = ((struct gui_img *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct gui_img *)ret)->label);
                 break;
 #endif
 #ifdef HAVE_TOUCHSCREEN
             case SKIN_FIND_TOUCHREGION:
-                ret = list.linkedlist->token->value.data;
-                itemlabel = ((struct touchregion *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct touchregion *)ret)->label);
                 break;
 #endif
 #ifdef HAVE_SKIN_VARIABLES
             case SKIN_VARIABLE:
-                ret = list.linkedlist->token->value.data;
-                itemlabel = ((struct skin_var *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_var *)ret)->label);
                 break;
 #endif
                 
         }
         if (!skip && itemlabel && !strcmp(itemlabel, label))
+        {
+            if (old_skin_buffer != skin_buffer)
+                skin_buffer = old_skin_buffer;
             return ret;
+        }
         
         if (isvplist)
-            list.vplist = list.vplist->next;
+            list.vplist = SKINOFFSETTOPTR(skin_buffer, list.vplist->next);
         else
-            list.linkedlist = list.linkedlist->next;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->next);
     }
+    if (old_skin_buffer != skin_buffer)
+        skin_buffer = old_skin_buffer;
     return NULL;
 }
 
@@ -212,10 +261,10 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token,
         token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token));
     if (!llitem || !token)
         return NULL;
-    llitem->next = NULL;
-    llitem->token = token;
+    llitem->next = PTRTOSKINOFFSET(skin_buffer, NULL);
+    llitem->token = PTRTOSKINOFFSET(skin_buffer, token);
     if (token_data)
-        llitem->token->value.data = token_data;
+        token->value.data = PTRTOSKINOFFSET(skin_buffer, token_data);
     return llitem;
 }
 
@@ -226,13 +275,12 @@ static int parse_statusbar_tags(struct skin_element* element,
     (void)element;
     if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR)
     {
-        token->value.data = (void*)&curr_vp->vp;
+        token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)&curr_vp->vp);
     }
     else
     {
-        struct skin_element *def_vp = wps_data->tree;
-        struct skin_viewport *default_vp = def_vp->data;
-        if (def_vp->params_count == 0)
+        struct skin_viewport *default_vp = SKINOFFSETTOPTR(skin_buffer, first_viewport->data);
+        if (first_viewport->params_count == 0)
         {
             wps_data->wps_sb_tag = true;
             wps_data->show_sb_on_wps = (token->type == SKIN_TOKEN_ENABLE_THEME);
@@ -279,7 +327,7 @@ static int parse_image_display(struct skin_element *element,
                                struct wps_token *token,
                                struct wps_data *wps_data)
 {
-    char *label = element->params[0].data.text;
+    char *label = get_param_text(element, 0);
     char sublabel = '\0';
     int subimage;
     struct gui_img *img;
@@ -297,9 +345,9 @@ static int parse_image_display(struct skin_element *element,
     {
         return WPS_ERROR_INVALID_PARAM;
     }
-    id->label = label;
+    id->label = img->label;
     id->offset = 0;
-    id->token = NULL;
+    id->token = PTRTOSKINOFFSET(skin_buffer, NULL);
     if (img->using_preloaded_icons)
     {
         token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
@@ -307,13 +355,13 @@ static int parse_image_display(struct skin_element *element,
     
     if (element->params_count > 1)
     {
-        if (element->params[1].type == CODE)
-            id->token = element->params[1].data.code->data;
+        if (get_param(element, 1)->type == CODE)
+            id->token = get_param_code(element, 1)->data;
         /* specify a number. 1 being the first subimage (i.e top) NOT 0 */
-        else if (element->params[1].type == INTEGER)
-            id->subimage = element->params[1].data.number - 1;
+        else if (get_param(element, 1)->type == INTEGER)
+            id->subimage = get_param(element, 1)->data.number - 1;
         if (element->params_count > 2)
-            id->offset = element->params[2].data.number;
+            id->offset = get_param(element, 2)->data.number;
     }
     else
     {
@@ -326,7 +374,7 @@ static int parse_image_display(struct skin_element *element,
             id->subimage = 0;
         }
     }
-    token->value.data = id;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, id);
     return 0;
 }
 
@@ -344,10 +392,10 @@ static int parse_image_load(struct skin_element *element,
        or %xl(n,filename.bmp,x,y,num_subimages)
     */
 
-    id = element->params[0].data.text;
-    filename = element->params[1].data.text;
-    x = element->params[2].data.number;
-    y = element->params[3].data.number;
+    id = get_param_text(element, 0);
+    filename = get_param_text(element, 1);
+    x = get_param(element, 2)->data.number;
+    y = get_param(element, 3)->data.number;
 
     /* check the image number and load state */
     if(skin_find_item(id, SKIN_FIND_IMAGE, wps_data))
@@ -360,7 +408,7 @@ static int parse_image_load(struct skin_element *element,
         return WPS_ERROR_INVALID_PARAM;
     /* save a pointer to the filename */
     img->bm.data = (char*)filename;
-    img->label = id;
+    img->label = PTRTOSKINOFFSET(skin_buffer, (void*)id);
     img->x = x;
     img->y = y;
     img->num_subimages = 1;
@@ -370,7 +418,7 @@ static int parse_image_load(struct skin_element *element,
     img->buflib_handle = -1;
 
     /* save current viewport */
-    img->vp = &curr_vp->vp;
+    img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
 
     if (token->type == SKIN_TOKEN_IMAGE_DISPLAY)
     {
@@ -378,7 +426,7 @@ static int parse_image_load(struct skin_element *element,
     }
     else if (element->params_count == 5)
     {
-        img->num_subimages = element->params[4].data.number;
+        img->num_subimages = get_param(element, 4)->data.number;
         if (img->num_subimages <= 0)
             return WPS_ERROR_INVALID_PARAM;
     }
@@ -408,13 +456,13 @@ static int parse_font_load(struct skin_element *element,
                            struct wps_data *wps_data)
 {
     (void)wps_data; (void)token;
-    int id = element->params[0].data.number;
-    char *filename = element->params[1].data.text;
+    int id = get_param(element, 0)->data.number;
+    char *filename = get_param_text(element, 1);
     int  glyphs;
     char *ptr;
     
     if(element->params_count > 2)
-        glyphs = element->params[2].data.number;
+        glyphs = get_param(element, 2)->data.number;
     else
         glyphs = GLYPHS_TO_CACHE;
     if (id < 2)
@@ -452,12 +500,12 @@ static int parse_playlistview(struct skin_element *element,
         (struct playlistviewer *)skin_buffer_alloc(sizeof(struct playlistviewer));
     if (!viewer)
         return WPS_ERROR_INVALID_PARAM;
-    viewer->vp = &curr_vp->vp;
+    viewer->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
     viewer->show_icons = true;
-    viewer->start_offset = element->params[0].data.number;
-    viewer->line = element->params[1].data.code;
+    viewer->start_offset = get_param(element, 0)->data.number;
+    viewer->line = PTRTOSKINOFFSET(skin_buffer, get_param_code(element, 1));
     
-    token->value.data = (void*)viewer;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)viewer);
     
     return 0;
 }
@@ -474,12 +522,12 @@ static int parse_viewport_gradient_setup(struct skin_element *element,
     cfg = (struct gradient_config *)skin_buffer_alloc(sizeof(struct gradient_config)); 
     if (!cfg)
         return 1;
-    if (!parse_color(curr_screen, element->params[0].data.text, &cfg->start) ||
-        !parse_color(curr_screen, element->params[1].data.text, &cfg->end))
+    if (!parse_color(curr_screen, get_param_text(element, 0), &cfg->start) ||
+        !parse_color(curr_screen, get_param_text(element, 1), &cfg->end))
         return 1;
     if (element->params_count > 2)
     {
-        if (!parse_color(curr_screen, element->params[2].data.text, &cfg->text))
+        if (!parse_color(curr_screen, get_param_text(element, 2), &cfg->text))
             return 1;
     }
     else
@@ -487,7 +535,7 @@ static int parse_viewport_gradient_setup(struct skin_element *element,
         cfg->text = curr_vp->vp.fg_pattern;
     }
 
-    token->value.data = cfg;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, cfg);
     return 0; 
 }
 #endif
@@ -500,14 +548,14 @@ static int parse_listitem(struct skin_element *element,
     struct listitem *li = (struct listitem *)skin_buffer_alloc(sizeof(struct listitem));
     if (!li)
         return 1;
-    token->value.data = li;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, li);
     if (element->params_count == 0)
         li->offset = 0;
     else
     {
-        li->offset = element->params[0].data.number;
+        li->offset = get_param(element, 0)->data.number;
         if (element->params_count > 1)
-            li->wrap = strcasecmp(element->params[1].data.text, "nowrap") != 0;
+            li->wrap = strcasecmp(get_param_text(element, 1), "nowrap") != 0;
         else
             li->wrap = true;
     }
@@ -526,17 +574,17 @@ static int parse_listitemviewport(struct skin_element *element,
         return -1;
     cfg->data = wps_data;
     cfg->tile = false;
-    cfg->label = element->params[0].data.text;
+    cfg->label = get_param_text(element, 0);
     cfg->width = -1;
     cfg->height = -1;
-    if (!isdefault(&element->params[1]))
-        cfg->width = element->params[1].data.number;
-    if (!isdefault(&element->params[2]))
-        cfg->height = element->params[2].data.number;
+    if (!isdefault(get_param(element, 1)))
+        cfg->width = get_param(element, 1)->data.number;
+    if (!isdefault(get_param(element, 2)))
+        cfg->height = get_param(element, 2)->data.number;
     if (element->params_count > 3 &&
-        !strcmp(element->params[3].data.text, "tile"))
+        !strcmp(get_param_text(element, 3), "tile"))
         cfg->tile = true;
-    token->value.data = (void*)cfg;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)cfg);
 #endif
     return 0;
 }
@@ -548,7 +596,7 @@ static int parse_viewporttextstyle(struct skin_element *element,
 {
     (void)wps_data;
     int style;
-    char *mode = element->params[0].data.text;
+    char *mode = get_param_text(element, 0);
     unsigned colour;
     
     if (!strcmp(mode, "invert"))
@@ -558,7 +606,7 @@ static int parse_viewporttextstyle(struct skin_element *element,
     else if (!strcmp(mode, "colour") || !strcmp(mode, "color"))
     {
         if (element->params_count < 2 ||
-            !parse_color(curr_screen, element->params[1].data.text, &colour))
+            !parse_color(curr_screen, get_param_text(element, 1), &colour))
             return 1;
         style = STYLE_COLORED|(STYLE_COLOR_MASK&colour); 
     }
@@ -571,7 +619,7 @@ static int parse_viewporttextstyle(struct skin_element *element,
         else /* atoi() instead of using a number in the parser is because [si]
               * will select the number for something which looks like a colour
               * making the "colour" case (above) harder to parse */
-            num_lines = atoi(element->params[1].data.text);
+            num_lines = atoi(get_param_text(element, 1));
         style = STYLE_GRADIENT|NUMLN_PACK(num_lines)|CURLN_PACK(0);
     }
 #endif
@@ -590,7 +638,7 @@ static int parse_viewportcolour(struct skin_element *element,
                                 struct wps_data *wps_data)
 {
     (void)wps_data;
-    struct skin_tag_parameter *param = element->params;
+    struct skin_tag_parameter *param = get_param(element, 0);
     struct viewport_colour *colour = 
         (struct viewport_colour *)skin_buffer_alloc(sizeof(struct viewport_colour));
     if (!colour)
@@ -602,11 +650,12 @@ static int parse_viewportcolour(struct skin_element *element,
     }
     else
     {
-        if (!parse_color(curr_screen, param->data.text, &colour->colour))
+        if (!parse_color(curr_screen, SKINOFFSETTOPTR(skin_buffer, param->data.text),
+                    &colour->colour))
             return -1;
     }
-    colour->vp = &curr_vp->vp;
-    token->value.data = colour;
+    colour->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, colour);
     if (element->line == curr_viewport_element->line)
     {
         if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR)
@@ -634,18 +683,18 @@ static int parse_image_special(struct skin_element *element,
     char *filename;
     if (token->type == SKIN_TOKEN_IMAGE_BACKDROP)
     {
-        if (isdefault(&element->params[0]))
+        if (isdefault(get_param(element, 0)))
         {
             filename = "-";
         }
         else
         {
-            filename = element->params[0].data.text;
+            filename = get_param_text(element, 0);
             /* format: %X(filename.bmp) or %X(d) */
             if (!strcmp(filename, "d"))
                 filename = NULL;
         }
-        wps_data->backdrop = filename;
+        backdrop_filename = filename;
     }
 #endif
 
@@ -665,7 +714,7 @@ static int parse_setting_and_lang(struct skin_element *element,
      * If that ever changes remove the #ifndef __PCTOOL__'s here 
      */
     (void)wps_data;
-    char *temp = element->params[0].data.text;
+    char *temp = get_param_text(element, 0);
     int i;
     
     if (token->type == SKIN_TOKEN_TRANSLATEDSTRING)
@@ -692,12 +741,12 @@ static int parse_logical_if(struct skin_element *element,
                              struct wps_data *wps_data)
 {
     (void)wps_data;
-    char *op = element->params[1].data.text;
+    char *op = get_param_text(element, 1);
     struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if));
     if (!lif)
         return -1;
-    token->value.data = lif;
-    lif->token = element->params[0].data.code->data;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, lif);
+    lif->token = get_param_code(element, 0)->data;
     
     if (!strncmp(op, "=", 1))
         lif->op = IF_EQUALS;
@@ -712,9 +761,9 @@ static int parse_logical_if(struct skin_element *element,
     else if (!strncmp(op, "<", 1))
         lif->op = IF_LESSTHAN;
     
-    memcpy(&lif->operand, &element->params[2], sizeof(lif->operand));
+    memcpy(&lif->operand, get_param(element, 2), sizeof(lif->operand));
     if (element->params_count > 3)
-        lif->num_options = element->params[3].data.number;
+        lif->num_options = get_param(element, 3)->data.number;
     else
         lif->num_options = TOKEN_VALUE_ONLY;
     return 0;
@@ -743,7 +792,7 @@ static int parse_timeout_tag(struct skin_element *element,
         }
     }
     else
-        val = element->params[0].data.number;
+        val = get_param(element, 0)->data.number;
     token->value.i = val * TIMEOUT_UNIT;
     return 0;
 }
@@ -756,13 +805,13 @@ static int parse_substring_tag(struct skin_element* element,
     struct substring *ss = (struct substring*)skin_buffer_alloc(sizeof(struct substring));
     if (!ss)
         return 1;
-    ss->start = element->params[0].data.number;
-    if (element->params[1].type == DEFAULT)
+    ss->start = get_param(element, 0)->data.number;
+    if (get_param(element, 1)->type == DEFAULT)
         ss->length = -1;
     else
-        ss->length = element->params[1].data.number;
-    ss->token = element->params[2].data.code->data;
-    token->value.data = ss;
+        ss->length = get_param(element, 1)->data.number;
+    ss->token = get_param_code(element, 2)->data;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, ss);
     return 0;
 }
 
@@ -773,7 +822,7 @@ static int parse_progressbar_tag(struct skin_element* element,
 #ifdef HAVE_LCD_BITMAP
     struct progressbar *pb;
     struct viewport *vp = &curr_vp->vp;
-    struct skin_tag_parameter *param = element->params;
+    struct skin_tag_parameter *param = get_param(element, 0);
     int curr_param = 0;
     char *image_filename = NULL;
     
@@ -782,17 +831,17 @@ static int parse_progressbar_tag(struct skin_element* element,
         return 0; /* nothing to do */
     pb = (struct progressbar*)skin_buffer_alloc(sizeof(struct progressbar));
     
-    token->value.data = pb;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, pb);
     
     if (!pb)
         return WPS_ERROR_INVALID_PARAM;
-    pb->vp = vp;
+    pb->vp = PTRTOSKINOFFSET(skin_buffer, vp);
     pb->follow_lang_direction = follow_lang_direction > 0;
     pb->nofill = false;
     pb->nobar = false;
-    pb->image = NULL;
-    pb->slider = NULL;
-    pb->backdrop = NULL;
+    pb->image = PTRTOSKINOFFSET(skin_buffer, NULL);
+    pb->slider = PTRTOSKINOFFSET(skin_buffer, NULL);
+    pb->backdrop = PTRTOSKINOFFSET(skin_buffer, NULL);
     pb->invert_fill_direction = false;
     pb->horizontal = true;
     
@@ -849,7 +898,7 @@ static int parse_progressbar_tag(struct skin_element* element,
     /* optional params, first is the image filename if it isnt recognised as a keyword */
     
     curr_param = 4;
-    if (isdefault(&element->params[curr_param]))
+    if (isdefault(get_param(element, curr_param)))
     {
         param++;
         curr_param++;
@@ -858,75 +907,79 @@ static int parse_progressbar_tag(struct skin_element* element,
     pb->horizontal = pb->width > pb->height;
     while (curr_param < element->params_count)
     {
+        char* text;
         param++;
-        if (!strcmp(param->data.text, "invert"))
+        text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
+        if (!strcmp(text, "invert"))
             pb->invert_fill_direction = true;
-        else if (!strcmp(param->data.text, "nofill"))
+        else if (!strcmp(text, "nofill"))
             pb->nofill = true;
-        else if (!strcmp(param->data.text, "nobar"))
+        else if (!strcmp(text, "nobar"))
             pb->nobar = true;
-        else if (!strcmp(param->data.text, "slider"))
+        else if (!strcmp(text, "slider"))
         {
             if (curr_param+1 < element->params_count)
             {
                 curr_param++;
                 param++;
-                pb->slider = skin_find_item(param->data.text, 
-                                            SKIN_FIND_IMAGE, wps_data);
+                text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
+                pb->slider = PTRTOSKINOFFSET(skin_buffer,
+                        skin_find_item(text, SKIN_FIND_IMAGE, wps_data));
             }
             else /* option needs the next param */
                 return -1;
         }
-        else if (!strcmp(param->data.text, "image"))
+        else if (!strcmp(text, "image"))
         {
             if (curr_param+1 < element->params_count)
             {
                 curr_param++;
                 param++;
-                image_filename = param->data.text;
-                
+                image_filename = SKINOFFSETTOPTR(skin_buffer, param->data.text);
             }
             else /* option needs the next param */
                 return -1;
         }
-        else if (!strcmp(param->data.text, "backdrop"))
+        else if (!strcmp(text, "backdrop"))
         {
             if (curr_param+1 < element->params_count)
             {
                 curr_param++;
                 param++;
-                pb->backdrop = skin_find_item(param->data.text, 
-                                              SKIN_FIND_IMAGE, wps_data);
+                text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
+                pb->backdrop = PTRTOSKINOFFSET(skin_buffer, 
+                        skin_find_item(text, SKIN_FIND_IMAGE, wps_data));
                 
             }
             else /* option needs the next param */
                 return -1;
         }
-        else if (!strcmp(param->data.text, "vertical"))
+        else if (!strcmp(text, "vertical"))
         {
             pb->horizontal = false;
-            if (isdefault(&element->params[3]))
+            if (isdefault(get_param(element, 3)))
                 pb->height = vp->height - pb->y;
         }
-        else if (!strcmp(param->data.text, "horizontal"))
+        else if (!strcmp(text, "horizontal"))
             pb->horizontal = true;
         else if (curr_param == 4)
-            image_filename = param->data.text;
+            image_filename = text;
             
         curr_param++;
     }
 
     if (image_filename)
     {
-        pb->image = skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data);
-        if (!pb->image) /* load later */
+        pb->image = PTRTOSKINOFFSET(skin_buffer, 
+                skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data));
+        if (!SKINOFFSETTOPTR(skin_buffer, pb->image)) /* load later */
         {           
             struct gui_img* img = (struct gui_img*)skin_buffer_alloc(sizeof(struct gui_img));
             if (!img)
                 return WPS_ERROR_INVALID_PARAM;
             /* save a pointer to the filename */
             img->bm.data = (char*)image_filename;
-            img->label = image_filename;
+            img->label = PTRTOSKINOFFSET(skin_buffer, image_filename);
             img->x = 0;
             img->y = 0;
             img->num_subimages = 1;
@@ -934,13 +987,13 @@ static int parse_progressbar_tag(struct skin_element* element,
             img->display = -1;
             img->using_preloaded_icons = false;
             img->buflib_handle = -1;
-            img->vp = &curr_vp->vp;
+            img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
             struct skin_token_list *item = 
                     (struct skin_token_list *)new_skin_token_list_item(NULL, img);
             if (!item)
                 return WPS_ERROR_INVALID_PARAM;
             add_to_ll_chain(&wps_data->images, item);
-            pb->image = img;
+            pb->image = PTRTOSKINOFFSET(skin_buffer, img);
         }
     }    
         
@@ -993,12 +1046,12 @@ static int parse_albumart_load(struct skin_element* element,
     aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */
     aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */
 
-    aa->x = element->params[0].data.number;
-    aa->y = element->params[1].data.number;
-    aa->width = element->params[2].data.number;
-    aa->height = element->params[3].data.number;
+    aa->x = get_param(element, 0)->data.number;
+    aa->y = get_param(element, 1)->data.number;
+    aa->width = get_param(element, 2)->data.number;
+    aa->height = get_param(element, 3)->data.number;
     
-    aa->vp = &curr_vp->vp;
+    aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
     aa->draw_handle = -1;
 
     /* if we got here, we parsed everything ok .. ! */
@@ -1016,7 +1069,7 @@ static int parse_albumart_load(struct skin_element* element,
         aa->x = LCD_WIDTH - (aa->x + aa->width);
 
     aa->state = WPS_ALBUMART_LOAD;
-    wps_data->albumart = aa;
+    wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, aa);
 
     dimensions.width = aa->width;
     dimensions.height = aa->height;
@@ -1026,9 +1079,9 @@ static int parse_albumart_load(struct skin_element* element,
     if (0 <= albumart_slot)
         wps_data->playback_aa_slot = albumart_slot;
         
-    if (element->params_count > 4 && !isdefault(&element->params[4]))
+    if (element->params_count > 4 && !isdefault(get_param(element, 4)))
     {
-        switch (*element->params[4].data.text)
+        switch (*get_param_text(element, 4))
         {
             case 'l':
             case 'L':
@@ -1050,9 +1103,9 @@ static int parse_albumart_load(struct skin_element* element,
                 break;
         }
     }
-    if (element->params_count > 5 && !isdefault(&element->params[5]))
+    if (element->params_count > 5 && !isdefault(get_param(element, 5)))
     {
-        switch (*element->params[5].data.text)
+        switch (*get_param_text(element, 5))
         {
             case 't':
             case 'T':
@@ -1082,7 +1135,7 @@ static struct skin_var* find_or_add_var(const char* label,
         ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var));
         if (!ret)
             return NULL;
-        ret->label = label;
+        ret->label = PTRTOSKINOFFSET(skin_buffer, label);
         ret->value = 1;
         ret->last_changed = 0xffff;
         struct skin_token_list *item = new_skin_token_list_item(NULL, ret);
@@ -1096,14 +1149,14 @@ static int parse_skinvar(  struct skin_element *element,
                            struct wps_token *token,
                            struct wps_data *wps_data)
 {
-    const char* label = element->params[0].data.text;
+    const char* label = get_param_text(element, 0);
     struct skin_var* var = find_or_add_var(label, wps_data);
     if (!var)
         return WPS_ERROR_INVALID_PARAM;
     switch (token->type)
     {
         case SKIN_TOKEN_VAR_GETVAL:
-            token->value.data = var;
+            token->value.data = PTRTOSKINOFFSET(skin_buffer, var);
             break;
         case SKIN_TOKEN_VAR_SET:
         {
@@ -1112,23 +1165,23 @@ static int parse_skinvar(  struct skin_element *element,
                                             sizeof(struct skin_var_changer));
             if (!data)
                 return WPS_ERROR_INVALID_PARAM;
-            data->var = var;
-            data->newval = element->params[2].data.number;
+            data->var = PTRTOSKINOFFSET(skin_buffer, var);
+            data->newval = get_param(element, 2)->data.number;
             data->max = 0;
-            if (!strcmp(element->params[1].data.text, "set"))
+            if (!strcmp(get_param_text(element, 1), "set"))
                 data->direct = true;
-            else if (!strcmp(element->params[1].data.text, "inc"))
+            else if (!strcmp(get_param_text(element, 1), "inc"))
             {
                 data->direct = false;
             }
-            else if (!strcmp(element->params[1].data.text, "dec"))
+            else if (!strcmp(get_param_text(element, 1), "dec"))
             {
                 data->direct = false;
                 data->newval *= -1;
             }
             if (element->params_count > 3)
-                data->max = element->params[3].data.number;
-            token->value.data = data;
+                data->max = get_param(element, 3)->data.number;
+            token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
         }
         break;
         case SKIN_TOKEN_VAR_TIMEOUT:
@@ -1138,12 +1191,12 @@ static int parse_skinvar(  struct skin_element *element,
                                             sizeof(struct skin_var_lastchange));
             if (!data)
                 return WPS_ERROR_INVALID_PARAM;
-            data->var = var;
+            data->var = PTRTOSKINOFFSET(skin_buffer, var);
             data->timeout = 10;
             if (element->params_count > 1)
-                data->timeout = element->params[1].data.number;
+                data->timeout = get_param(element, 1)->data.number;
             data->timeout *= TIMEOUT_UNIT;
-            token->value.data = data;
+            token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
         }
         break;
         default: /* kill the warning */
@@ -1161,23 +1214,25 @@ static int parse_lasttouch(struct skin_element *element,
             (struct touchregion_lastpress*)skin_buffer_alloc(
                                 sizeof(struct touchregion_lastpress));
     int i;
+    struct touchregion *region = NULL;
     if (!data)
         return WPS_ERROR_INVALID_PARAM;
-    data->region = NULL;
+    
     data->timeout = 10;
     
     for (i=0; i<element->params_count; i++)
     {
-        if (element->params[i].type == STRING)
-            data->region = skin_find_item(element->params[i].data.text,
+        if (get_param(element, i)->type == STRING)
+            region = skin_find_item(get_param_text(element, i),
                                           SKIN_FIND_TOUCHREGION, wps_data);
-        else if (element->params[i].type == INTEGER ||
-                 element->params[i].type == DECIMAL)
-            data->timeout = element->params[i].data.number;
+        else if (get_param(element, i)->type == INTEGER ||
+                 get_param(element, i)->type == DECIMAL)
+            data->timeout = get_param(element, i)->data.number;
     }
 
+    data->region = PTRTOSKINOFFSET(skin_buffer, region);
     data->timeout *= TIMEOUT_UNIT;
-    token->value.data = data;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
     return 0;
 }
 
@@ -1221,7 +1276,7 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no,
 {
 #ifndef __PCTOOL__
     int p = param_no;
-    char *name = element->params[p++].data.text;
+    char *name = get_param_text(element, p++);
     int j;
 
     region->setting_data.setting = find_setting_by_cfgname(name, &j);
@@ -1237,11 +1292,11 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no,
         if (element->params_count < p+1)
             return -1;
 
-        text = element->params[p++].data.text;
+        text = get_param_text(element, p++);
         switch (settings[j].flags&F_T_MASK)
         {
         case F_T_CUSTOM:
-            setting->value.text = text;
+            setting->value.text = PTRTOSKINOFFSET(skin_buffer, text);
             break;                              
         case F_T_INT:
         case F_T_UINT:
@@ -1301,34 +1356,34 @@ static int parse_touchregion(struct skin_element *element,
     /* should probably do some bounds checking here with the viewport... but later */
     region->action = ACTION_NONE;
     
-    if (element->params[0].type == STRING)
+    if (get_param(element, 0)->type == STRING)
     {
-        region->label = element->params[0].data.text;
+        region->label = PTRTOSKINOFFSET(skin_buffer, get_param_text(element, 0));
         p = 1;
         /* "[SI]III[SI]|SS" is the param list. There MUST be 4 numbers
          * followed by at least one string. Verify that here */
         if (element->params_count < 6 ||
-            element->params[4].type != INTEGER)
+            get_param(element, 4)->type != INTEGER)
             return WPS_ERROR_INVALID_PARAM;
     }
     else
     {
-        region->label = NULL;
+        region->label = PTRTOSKINOFFSET(skin_buffer, NULL);
         p = 0;
     }
     
-    region->x = element->params[p++].data.number;
-    region->y = element->params[p++].data.number;
-    region->width = element->params[p++].data.number;
-    region->height = element->params[p++].data.number;
-    region->wvp = curr_vp;
+    region->x = get_param(element, p++)->data.number;
+    region->y = get_param(element, p++)->data.number;
+    region->width = get_param(element, p++)->data.number;
+    region->height = get_param(element, p++)->data.number;
+    region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp);
     region->armed = false;
     region->reverse_bar = false;
     region->value = 0;
     region->last_press = 0xffff;
     region->press_length = PRESS;
     region->allow_while_locked = false;
-    action = element->params[p++].data.text;
+    action = get_param_text(element, p++);
 
     /* figure out the action */
     if(!strcmp(pb_string, action))
@@ -1364,7 +1419,7 @@ static int parse_touchregion(struct skin_element *element,
     }
     while (p < element->params_count)
     {
-        char* param = element->params[p++].data.text;
+        char* param = get_param_text(element, p++);
         if (!strcmp(param, "allow_while_locked"))
             region->allow_while_locked = true;
         else if (!strcmp(param, "reverse_bar"))
@@ -1441,21 +1496,26 @@ void skin_data_free_buflib_allocs(struct wps_data *wps_data)
     (void)wps_data;
 #ifdef HAVE_LCD_BITMAP
 #ifndef __PCTOOL__
-    struct skin_token_list *list = wps_data->images;
+    struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
+    int *font_ids = SKINOFFSETTOPTR(skin_buffer, wps_data->font_ids);
     while (list)
     {
-        struct gui_img *img = (struct gui_img*)list->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
+        struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         if (img->buflib_handle > 0)
             core_free(img->buflib_handle);
-        list = list->next;
+        list = SKINOFFSETTOPTR(skin_buffer, list->next);
     }
-    wps_data->images = NULL;
-    if (wps_data->font_ids != NULL)
+    wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL);
+    if (font_ids != NULL)
     {
         while (wps_data->font_count > 0)
-            font_unload(wps_data->font_ids[--wps_data->font_count]);
+            font_unload(font_ids[--wps_data->font_count]);
     }
-    wps_data->font_ids = NULL;
+    wps_data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
+    if (wps_data->buflib_handle > 0)
+        core_free(wps_data->buflib_handle);
+    wps_data->buflib_handle = -1;
 #endif
 #endif
 }
@@ -1469,22 +1529,22 @@ static void skin_data_reset(struct wps_data *wps_data)
 {
     skin_data_free_buflib_allocs(wps_data);
 #ifdef HAVE_LCD_BITMAP
-    wps_data->images = NULL;
+    wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
-    wps_data->tree = NULL;
+    wps_data->tree = PTRTOSKINOFFSET(skin_buffer, NULL);
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
     if (wps_data->backdrop_id >= 0)
         skin_backdrop_unload(wps_data->backdrop_id);
-    wps_data->backdrop = NULL;
+    backdrop_filename = NULL;
 #endif
 #ifdef HAVE_TOUCHSCREEN
-    wps_data->touchregions = NULL;
+    wps_data->touchregions = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
 #ifdef HAVE_SKIN_VARIABLES
-    wps_data->skinvars = NULL;
+    wps_data->skinvars = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
 #ifdef HAVE_ALBUMART
-    wps_data->albumart = NULL;
+    wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, NULL);
     if (wps_data->playback_aa_slot >= 0)
     {
         playback_release_aa_slot(wps_data->playback_aa_slot);
@@ -1600,16 +1660,17 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
     bool retval = true; /* return false if a single image failed to load */
     
     /* regular images */
-    list = wps_data->images;
+    list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
     while (list)
     {
-        struct gui_img *img = (struct gui_img*)list->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
+        struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         if (img->bm.data)
         {
             if (img->using_preloaded_icons)
             {
                 img->loaded = true;
-                list->token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
+                token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
             }
             else
             {
@@ -1621,11 +1682,11 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
                     retval = false;
             }
         }
-        list = list->next;
+        list = SKINOFFSETTOPTR(skin_buffer, list->next);
     }
 
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
-    wps_data->backdrop_id = skin_backdrop_assign(wps_data->backdrop, bmpdir, curr_screen);
+    wps_data->backdrop_id = skin_backdrop_assign(backdrop_filename, bmpdir, curr_screen);
 #endif /* has backdrop support */
     return retval;
 }
@@ -1639,11 +1700,12 @@ static bool skin_load_fonts(struct wps_data *data)
     struct skin_element *vp_list;
     int font_id;
     /* walk though each viewport and assign its font */
-    for(vp_list = data->tree; vp_list; vp_list = vp_list->next)
+    for(vp_list = SKINOFFSETTOPTR(skin_buffer, data->tree);
+        vp_list; vp_list = SKINOFFSETTOPTR(skin_buffer, vp_list->next))
     {
         /* first, find the viewports that have a non-sys/ui-font font */
         struct skin_viewport *skin_vp =
-                (struct skin_viewport*)vp_list->data;
+                SKINOFFSETTOPTR(skin_buffer, vp_list->data);
         struct viewport *vp = &skin_vp->vp;
 
         font_id = skin_vp->parsed_fontid;
@@ -1699,19 +1761,28 @@ static bool skin_load_fonts(struct wps_data *data)
         /* finally, assign the font_id to the viewport */
         vp->font = font->id;
     }
-    data->font_ids = skin_buffer_alloc(font_count * sizeof(int));
-    if (!success || data->font_ids == NULL)
+    if (font_count)
     {
-        while (font_count > 0)
+        int *font_ids = skin_buffer_alloc(font_count * sizeof(int));
+        if (!success || font_ids == NULL)
         {
-            if(id_array[--font_count] != -1)
-                font_unload(id_array[font_count]);
+            while (font_count > 0)
+            {
+                if(id_array[--font_count] != -1)
+                    font_unload(id_array[font_count]);
+            }
+            data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
+            return false;
         }
-        data->font_ids = NULL;
-        return false;
+        memcpy(font_ids, id_array, sizeof(int)*font_count);
+        data->font_count = font_count;
+        data->font_ids = PTRTOSKINOFFSET(skin_buffer, font_ids);
+    }
+    else
+    {
+        data->font_count = 0;
+        data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
     }
-    memcpy(data->font_ids, id_array, sizeof(int)*font_count);
-    data->font_count = font_count;
     return success;
 }
 
@@ -1726,13 +1797,15 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
         return CALLBACK_ERROR;
         
     skin_vp->hidden_flags = 0;
-    skin_vp->label = NULL;
+    skin_vp->label = PTRTOSKINOFFSET(skin_buffer, NULL);
     skin_vp->is_infovp = false;
     skin_vp->parsed_fontid = 1;
-    element->data = skin_vp;
+    element->data = PTRTOSKINOFFSET(skin_buffer, skin_vp);
     curr_vp = skin_vp;
     curr_viewport_element = element;
-    
+    if (!first_viewport)
+        first_viewport = element;
+
     viewport_set_defaults(&skin_vp->vp, curr_screen);
     
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
@@ -1746,11 +1819,11 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
 #endif
     
 
-    struct skin_tag_parameter *param = element->params;
+    struct skin_tag_parameter *param = get_param(element, 0);
     if (element->params_count == 0) /* default viewport */
     {
-        if (!data->tree) /* first viewport in the skin */
-            data->tree = element;
+        if (data->tree < 0) /* first viewport in the skin */
+            data->tree = PTRTOSKINOFFSET(skin_buffer, element);
         skin_vp->label = VP_DEFAULT_LABEL;
         return CALLBACK_OK;
     }
@@ -1848,6 +1921,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
             token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token));
             memset(token, 0, sizeof(*token));
             token->type = element->tag->type;
+            token->value.data = -1;
             
             if (element->tag->flags&SKIN_RTC_REFRESH)
             {
@@ -1860,7 +1934,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
             else
                 curr_line->update_mode |= element->tag->flags&SKIN_REFRESH_ALL;
             
-            element->data = token;
+            element->data = PTRTOSKINOFFSET(skin_buffer, token);
             
             /* Some tags need special handling for the tag, so add them here */
             switch (token->type)
@@ -1909,7 +1983,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
                     break;
 #endif
                 case SKIN_TOKEN_FILE_DIRECTORY:
-                    token->value.i = element->params[0].data.number;
+                    token->value.i = get_param(element, 0)->data.number;
                     break;
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
                 case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
@@ -1941,7 +2015,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
                     break;
                 case SKIN_TOKEN_VIEWPORT_ENABLE:
                 case SKIN_TOKEN_UIVIEWPORT_ENABLE:
-                    token->value.data = element->params[0].data.text;
+                    token->value.data = get_param(element, 0)->data.text;
                     break;
                 case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
                     function = parse_image_display;
@@ -1964,8 +2038,11 @@ static int skin_element_callback(struct skin_element* element, void* data)
 #endif
 #ifdef HAVE_ALBUMART
                 case SKIN_TOKEN_ALBUMART_DISPLAY:
-                    if (wps_data->albumart)
-                        wps_data->albumart->vp = &curr_vp->vp;
+                    if (SKINOFFSETTOPTR(skin_buffer, wps_data->albumart))
+                    {
+                        struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
+                        aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
+                    }
                     break;
                 case SKIN_TOKEN_ALBUMART_LOAD:
                     function = parse_albumart_load;
@@ -2002,7 +2079,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
                 (struct line *)skin_buffer_alloc(sizeof(struct line));
             line->update_mode = SKIN_REFRESH_STATIC;
             curr_line = line;
-            element->data = line;
+            element->data = PTRTOSKINOFFSET(skin_buffer, line);
         }
         break;
         case LINE_ALTERNATOR:
@@ -2013,7 +2090,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
 #ifndef __PCTOOL__
             alternator->next_change_tick = current_tick;
 #endif
-            element->data = alternator;
+            element->data = PTRTOSKINOFFSET(skin_buffer, alternator);
         }
         break;
         case CONDITIONAL:
@@ -2022,7 +2099,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
                 (struct conditional *)skin_buffer_alloc(sizeof(struct conditional));
             conditional->last_value = -1;
             conditional->token = element->data;
-            element->data = conditional;
+            element->data = PTRTOSKINOFFSET(skin_buffer, conditional);
             if (!check_feature_tag(element->tag->type))
             {
                 return FEATURE_NOT_AVAILABLE;
@@ -2051,11 +2128,12 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
     struct mp3entry *curtrack;
     long offset;
     struct skin_albumart old_aa = {.state = WPS_ALBUMART_NONE};
-    if (wps_data->albumart)
+    struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
+    if (aa)
     {
-        old_aa.state = wps_data->albumart->state;
-        old_aa.height = wps_data->albumart->height;
-        old_aa.width = wps_data->albumart->width;
+        old_aa.state = aa->state;
+        old_aa.height = aa->height;
+        old_aa.width = aa->width;
     }
 #endif
 #ifdef HAVE_LCD_BITMAP
@@ -2074,12 +2152,20 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
 #endif
 
 
+        /* get buffer space from the plugin buffer */
+    size_t buffersize = 0;
+    wps_buffer = (char *)plugin_get_buffer(&buffersize);
+
+    if (!wps_buffer)
+        return false;
+
     skin_data_reset(wps_data);
     wps_data->wps_loaded = false;
     curr_screen = screen;
     curr_line = NULL;
     curr_vp = NULL;
     curr_viewport_element = NULL;
+    first_viewport = NULL;
 
     if (isfile)
     {
@@ -2087,14 +2173,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
 
         if (fd < 0)
             return false;
-
-        /* get buffer space from the plugin buffer */
-        size_t buffersize = 0;
-        wps_buffer = (char *)plugin_get_buffer(&buffersize);
-
-        if (!wps_buffer)
-            return false;
-
         /* copy the file's content to the buffer for parsing,
            ensuring that every line ends with a newline char. */
         unsigned int start = 0;
@@ -2110,25 +2188,26 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
         close(fd);
         if (start <= 0)
             return false;
+        skin_buffer = &wps_buffer[start];
+        buffersize -= start;
     }
     else
     {
+        skin_buffer = wps_buffer;
         wps_buffer = (char*)buf;
     }
+    skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3);
+    buffersize -= 3;
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-    wps_data->backdrop = "-";
+    backdrop_filename = "-";
     wps_data->backdrop_id = -1;
 #endif
     /* parse the skin source */
-#ifndef APPLICATION
-    skin_buffer_save_position();
-#endif
-    wps_data->tree = skin_parse(wps_buffer, skin_element_callback, wps_data);
-    if (!wps_data->tree) {
+    skin_buffer_init(skin_buffer, buffersize);
+    struct skin_element *tree = skin_parse(wps_buffer, skin_element_callback, wps_data);
+    wps_data->tree = PTRTOSKINOFFSET(skin_buffer, tree);
+    if (!SKINOFFSETTOPTR(skin_buffer, wps_data->tree)) {
         skin_data_reset(wps_data);
-#ifndef APPLICATION
-        skin_buffer_restore_position();
-#endif
         return false;
     }
 
@@ -2149,9 +2228,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
         !skin_load_fonts(wps_data)) 
     {
         skin_data_reset(wps_data);
-#ifndef APPLICATION
-        skin_buffer_restore_position();
-#endif
         return false;
     }
 #endif
@@ -2159,7 +2235,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
     status = audio_status();
     if (status & AUDIO_STATUS_PLAY)
     {
-        struct skin_albumart *aa = wps_data->albumart;
+        struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
         if (aa && ((aa->state && !old_aa.state) ||
             (aa->state &&
             (((old_aa.height != aa->height) ||
@@ -2173,7 +2249,14 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
         }
     }
 #endif
-    wps_data->wps_loaded = true;
+    wps_data->buflib_handle = core_alloc(isfile ? buf : "failsafe skin",
+                                            skin_buffer_usage());
+    if (wps_data->buflib_handle >= 0)
+    {
+        wps_data->wps_loaded = true;
+        memcpy(core_get_data(wps_data->buflib_handle), skin_buffer,
+                skin_buffer_usage());
+    }
 #ifdef DEBUG_SKIN_ENGINE
  //   if (isfile && debug_wps)
  //       debug_skin_usage();
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 4d41a6f..e408caa 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -27,6 +27,7 @@
 #include "strlcat.h"
 
 #include "config.h"
+#include "core_alloc.h"
 #include "kernel.h"
 #ifdef HAVE_ALBUMART
 #include "albumart.h"
@@ -81,6 +82,18 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
                                        unsigned long refresh_type);
 #endif
 
+static char* skin_buffer;
+/* hack alert: fix skin_parser.c's skin_buffer pointer */
+void skinparser_set_buffer(char* pointer);
+
+static inline struct skin_element*
+get_child(OFFSETTYPE(struct skin_element**) children, int child)
+{
+    OFFSETTYPE(struct skin_element*) *kids = SKINOFFSETTOPTR(skin_buffer, children);
+    return SKINOFFSETTOPTR(skin_buffer, kids[child]);
+}
+
+
 static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
                              struct skin_element *element, struct viewport* vp)
 {
@@ -88,7 +101,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
     (void)vp; /* silence warnings */
     (void)info;
 #endif    
-    struct wps_token *token = (struct wps_token *)element->data;
+    struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data);
 
 #ifdef HAVE_LCD_BITMAP
     struct wps_data *data = gwps->data;
@@ -99,14 +112,16 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
         case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
         {
-            struct viewport_colour *col = token->value.data;
-            col->vp->fg_pattern = col->colour;
+            struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
+            vp->fg_pattern = col->colour;
         }
         break;
         case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
         {
-            struct viewport_colour *col = token->value.data;
-            col->vp->bg_pattern = col->colour;
+            struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
+            vp->bg_pattern = col->colour;
         }
         break;
         case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
@@ -116,7 +131,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
 #ifdef HAVE_LCD_COLOR
         case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP:
         {
-            struct gradient_config *cfg = token->value.data;
+            struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data);
             vp->lss_pattern = cfg->start;
             vp->lse_pattern = cfg->end;
             vp->lst_pattern = cfg->text;
@@ -125,14 +140,18 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
 #endif
         case SKIN_TOKEN_VIEWPORT_ENABLE:
         {
-            char *label = token->value.data;
+            char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
             char temp = VP_DRAW_HIDEABLE;
-            struct skin_element *viewport = gwps->data->tree;
+            struct skin_element *viewport = SKINOFFSETTOPTR(skin_buffer, gwps->data->tree);
             while (viewport)
             {
-                struct skin_viewport *skinvp = (struct skin_viewport*)viewport->data;
-                if (skinvp->label && !skinvp->is_infovp &&
-                    !strcmp(skinvp->label, label))
+                struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data);
+                
+                char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label);
+                if (skinvp->label == VP_DEFAULT_LABEL)
+                    vplabel = VP_DEFAULT_LABEL_STRING;
+                if (vplabel && !skinvp->is_infovp &&
+                    !strcmp(vplabel, label))
                 {
                     if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
                     {
@@ -140,7 +159,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
                     }    
                     skinvp->hidden_flags = temp;
                 }
-                viewport = viewport->next;
+                viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next);
             }
         }
         break;
@@ -148,11 +167,10 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_LIST_ITEM_CFG:
             if (do_refresh)
                 skinlist_set_cfg(gwps->display->screen_type, 
-                                    token->value.data);
+                                    SKINOFFSETTOPTR(skin_buffer, token->value.data));
             break;
         case SKIN_TOKEN_UIVIEWPORT_ENABLE:
-            sb_set_info_vp(gwps->display->screen_type, 
-                           token->value.data);
+            sb_set_info_vp(gwps->display->screen_type, token->value.data);
             break;
         case SKIN_TOKEN_PEAKMETER:
             data->peak_meter_enabled = true;
@@ -173,7 +191,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_TUNER_RSSI_BAR:
         case SKIN_TOKEN_LIST_SCROLLBAR:
         {
-            struct progressbar *bar = (struct progressbar*)token->value.data;
+            struct progressbar *bar = (struct progressbar*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
             if (do_refresh)
                 draw_progressbar(gwps, info->line_number, bar);
         }
@@ -183,12 +201,12 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:
         case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
         {
-            struct image_display *id = token->value.data;
-            const char* label = id->label;
+            struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
             struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data);
             if (img && img->loaded)
             {
-                if (id->token == NULL)
+                if (SKINOFFSETTOPTR(skin_buffer, id->token) == NULL)
                 {
                     img->display = id->subimage;
                 }
@@ -197,8 +215,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
                     char buf[16];
                     const char *out;
                     int a = img->num_subimages;
-                    out = get_token_value(gwps, id->token, info->offset, 
-                                          buf, sizeof(buf), &a);
+                    out = get_token_value(gwps, SKINOFFSETTOPTR(skin_buffer, id->token),
+                            info->offset, buf, sizeof(buf), &a);
 
                     /* NOTE: get_token_value() returns values starting at 1! */
                     if (a == -1)
@@ -224,29 +242,32 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         }
 #ifdef HAVE_ALBUMART
         case SKIN_TOKEN_ALBUMART_DISPLAY:
+        {
+            struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
             /* now draw the AA */
-            if (do_refresh && data->albumart)
+            if (do_refresh && aa)
             {
                 int handle = playback_current_aa_hid(data->playback_aa_slot);
 #if CONFIG_TUNER
                 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
                 {
-                    struct dim dim = {data->albumart->width, data->albumart->height};
+                    struct dim dim = {aa->width, aa->height};
                     handle = radio_get_art_hid(&dim);
                 }
 #endif
-                data->albumart->draw_handle = handle;
+                aa->draw_handle = handle;
             }
             break;
+        }
 #endif
         case SKIN_TOKEN_DRAW_INBUILTBAR:
             gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]),
                                info->refresh_type == SKIN_REFRESH_ALL,
-                               token->value.data);
+                               SKINOFFSETTOPTR(skin_buffer, token->value.data));
             break;
         case SKIN_TOKEN_VIEWPORT_CUSTOMLIST:
             if (do_refresh)
-                skin_render_playlistviewer(token->value.data, gwps,
+                skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps,
                                            info->skin_vp, info->refresh_type);
             break;
         
@@ -255,23 +276,24 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_VAR_SET:
             if (do_refresh)
             {
-                struct skin_var_changer *data = token->value.data;
+                struct skin_var_changer *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                struct skin_var *var = SKINOFFSETTOPTR(skin_buffer, data->var);
                 if (data->direct)
-                    data->var->value = data->newval;
+                    var->value = data->newval;
                 else
                 {
-                    data->var->value += data->newval;
+                    var->value += data->newval;
                     if (data->max)
                     {
-                        if (data->var->value > data->max)
-                            data->var->value = 1;
-                        else if (data->var->value < 1)
-                            data->var->value = data->max;
+                        if (var->value > data->max)
+                            var->value = 1;
+                        else if (var->value < 1)
+                            var->value = data->max;
                     }
                 }
-                if (data->var->value < 1)
-                    data->var->value = 1;
-                data->var->last_changed = current_tick;
+                if (var->value < 1)
+                    var->value = 1;
+                var->last_changed = current_tick;
             }
             break;
 #endif
@@ -289,7 +311,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
 #ifdef HAVE_LCD_BITMAP
     struct gui_wps *gwps = info->gwps;
     struct wps_data *data = gwps->data;
-#endif    
+#endif
     /* Tags here are ones which need to be "turned off" or cleared 
      * if they are in a conditional branch which isnt being used */
     if (branch->type == LINE_ALTERNATOR)
@@ -297,12 +319,12 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
         int i;
         for (i=0; i<branch->children_count; i++)
         {
-            do_tags_in_hidden_conditional(branch->children[i], info);
+            do_tags_in_hidden_conditional(get_child(branch->children, i), info);
         }
     }
     else if (branch->type == LINE && branch->children_count)
     {
-        struct skin_element *child = branch->children[0];
+        struct skin_element *child = get_child(branch->children, 0);
 #if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART)
         struct wps_token *token;
 #endif
@@ -313,25 +335,25 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
                 int i;
                 for (i=0; i<child->children_count; i++)
                 {
-                    do_tags_in_hidden_conditional(child->children[i], info);
+                    do_tags_in_hidden_conditional(get_child(child->children, i), info);
                 }
-                child = child->next;
+                child = SKINOFFSETTOPTR(skin_buffer, child->next);
                 continue;
             }
-            else if (child->type != TAG || !child->data)
+            else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data))
             {
-                child = child->next;
+                child = SKINOFFSETTOPTR(skin_buffer, child->next);
                 continue;
             }
 #if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART)
-            token = (struct wps_token *)child->data;
+            token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data);
 #endif
 #ifdef HAVE_LCD_BITMAP
             /* clear all pictures in the conditional and nested ones */
             if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY)
             {
-                struct image_display *id = token->value.data;
-                struct gui_img *img = skin_find_item(id->label, 
+                struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), 
                                                      SKIN_FIND_IMAGE, data);
                 clear_image_pos(gwps, img);
             }
@@ -341,14 +363,18 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
             }
             else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE)
             {
-                char *label = token->value.data;
+                char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
                 struct skin_element *viewport;
-                for (viewport = data->tree;
+                for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
                      viewport;
-                     viewport = viewport->next)
+                     viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
                 {
-                    struct skin_viewport *skin_viewport = (struct skin_viewport*)viewport->data;
-                    if (skin_viewport->label && strcmp(skin_viewport->label, label))
+                    struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
+                    
+                    char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
+                    if (skin_viewport->label == VP_DEFAULT_LABEL)
+                        vplabel = VP_DEFAULT_LABEL_STRING;
+                    if (vplabel && strcmp(vplabel, label))
                         continue;
                     if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE)
                     {
@@ -377,7 +403,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
                         playback_current_aa_hid(data->playback_aa_slot), true);
             }
 #endif
-            child = child->next;
+            child = SKINOFFSETTOPTR(skin_buffer, child->next);
         }
     }
 }
@@ -433,7 +459,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
     if (line->children_count == 0)
         return false; /* empty line, do nothing */
         
-    struct skin_element *child = line->children[0];
+    struct skin_element *child = get_child(line->children, 0);
     struct conditional *conditional;
     skin_render_func func = skin_render_line;
     int old_refresh_mode = info->refresh_type;
@@ -442,7 +468,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
         switch (child->type)
         {
             case CONDITIONAL:
-                conditional = (struct conditional*)child->data;
+                conditional = SKINOFFSETTOPTR(skin_buffer, child->data);
                 last_value = conditional->last_value;
                 value = evaluate_conditional(info->gwps, info->offset, 
                                              conditional, child->children_count);
@@ -456,20 +482,20 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
                     {
                         /* we are in a false branch of a %?aa<true> conditional */
                         if (last_value == 0)
-                            do_tags_in_hidden_conditional(child->children[0], info);
+                            do_tags_in_hidden_conditional(get_child(child->children, 0), info);
                         break;
                     }
                 }
                 else
                 {
                     if (last_value >= 0 && value != last_value && last_value < child->children_count)
-                        do_tags_in_hidden_conditional(child->children[last_value], info);
+                        do_tags_in_hidden_conditional(get_child(child->children, last_value), info);
                 }
-                if (child->children[value]->type == LINE_ALTERNATOR)
+                if (get_child(child->children, value)->type == LINE_ALTERNATOR)
                 {
                     func = skin_render_alternator;
                 }
-                else if (child->children[value]->type == LINE)
+                else if (get_child(child->children, value)->type == LINE)
                     func = skin_render_line;
                 
                 if (value != last_value)
@@ -478,7 +504,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
                     info->force_redraw = true;
                 }
                     
-                if (func(child->children[value], info))
+                if (func(get_child(child->children, value), info))
                     needs_update = true;
                 else
                     needs_update = needs_update || (last_value != value);
@@ -493,14 +519,14 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
                 
                 fix_line_alignment(info, child);
                 
-                if (!child->data)
+                if (!SKINOFFSETTOPTR(skin_buffer, child->data))
                 {
                     break;
                 }
                 if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp))
                 {
                     static char tempbuf[128];
-                    const char *valuestr = get_token_value(info->gwps, child->data,
+                    const char *valuestr = get_token_value(info->gwps, SKINOFFSETTOPTR(skin_buffer, child->data),
                                                         info->offset, tempbuf,
                                                         sizeof(tempbuf), NULL);
                     if (valuestr)
@@ -517,7 +543,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
                 }
                 break;
             case TEXT:
-                strlcat(info->cur_align_start, child->data, 
+                strlcat(info->cur_align_start, SKINOFFSETTOPTR(skin_buffer, child->data), 
                         info->buf_size - (info->cur_align_start-info->buf));
                 needs_update = needs_update || 
                                 (info->refresh_type&SKIN_REFRESH_STATIC) != 0;
@@ -527,7 +553,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
                 break;
         }
 
-        child = child->next;
+        child = SKINOFFSETTOPTR(skin_buffer, child->next);
     }
     return needs_update;
 }
@@ -541,29 +567,29 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
     {
         if (element->children_count == 0)
             return retval; /* empty line, so force redraw */
-        element = element->children[0];
+        element = get_child(element->children, 0);
     }
     while (element)
     {
         if (element->type == TAG &&
             element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT )
         {
-            token = element->data;
+            token = SKINOFFSETTOPTR(skin_buffer, element->data);
             return token->value.i;
         }
         else if (element->type == CONDITIONAL)
         {
-            struct conditional *conditional = element->data;
+            struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data);
             int val = evaluate_conditional(gwps, 0, conditional,
                                            element->children_count);
             if (val >= 0)
             {
-                retval = get_subline_timeout(gwps, element->children[val]);
+                retval = get_subline_timeout(gwps, get_child(element->children, val));
                 if (retval >= 0)
                     return retval;
             }
         }
-        element = element->next;
+        element = SKINOFFSETTOPTR(skin_buffer, element->next);
     }
     return retval;
 }
@@ -571,7 +597,7 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
 bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
 {
     bool changed_lines = false;
-    struct line_alternator *alternator = (struct line_alternator*)element->data;
+    struct line_alternator *alternator = SKINOFFSETTOPTR(skin_buffer, element->data);
     unsigned old_refresh = info->refresh_type;
     if (info->refresh_type == SKIN_REFRESH_ALL)
     {
@@ -597,11 +623,11 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
             try_line++;
             if (try_line >= element->children_count)
                 try_line = 0;
-            if (element->children[try_line]->children_count != 0)
+            if (get_child(element->children, try_line)->children_count != 0)
             {
-                current_line = element->children[try_line];
+                current_line = get_child(element->children, try_line);
                 rettimeout = get_subline_timeout(info->gwps, 
-                                                 current_line->children[0]);
+                                    get_child(current_line->children, 0));
                 if (rettimeout > 0)
                 {
                     suitable = true;
@@ -619,7 +645,7 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
         info->refresh_type = SKIN_REFRESH_ALL;
         info->force_redraw = true;
     }
-    bool ret = skin_render_line(element->children[alternator->current_line], info);
+    bool ret = skin_render_line(get_child(element->children, alternator->current_line), info);
     info->refresh_type = old_refresh;
     return changed_lines || ret;
 }
@@ -646,14 +672,17 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
     
     struct align_pos * align = &info.align;
     bool needs_update;
+    skin_buffer = get_skin_buffer(gwps->data);
+    skinparser_set_buffer(skin_buffer);
 #ifdef HAVE_LCD_BITMAP
     /* Set images to not to be displayed */
-    struct skin_token_list *imglist = gwps->data->images;
+    struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, gwps->data->images);
     while (imglist)
     {
-        struct gui_img *img = (struct gui_img *)imglist->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
+        struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         img->display = -1;
-        imglist = imglist->next;
+        imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
     }
 
     /* fix font ID's */
@@ -716,7 +745,7 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
         }
         if (!info.no_line_break)
             info.line_number++;
-        line = line->next;
+        line = SKINOFFSETTOPTR(skin_buffer, line->next);
     }
 #ifdef HAVE_LCD_BITMAP
     wps_display_images(gwps, &skin_viewport->vp);
@@ -730,8 +759,11 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
     
     struct skin_element* viewport;
     struct skin_viewport* skin_viewport;
+    char *label;
     
     int old_refresh_mode = refresh_mode;
+    skin_buffer = get_skin_buffer(gwps->data);
+    skinparser_set_buffer(skin_buffer);
     
 #ifdef HAVE_LCD_CHARCELLS
     int i;
@@ -741,18 +773,21 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
             data->wps_progress_pat[i] = display->get_locked_pattern();
     }
 #endif
-    viewport = data->tree;
-    skin_viewport = (struct skin_viewport *)viewport->data;
-    if (skin_viewport->label && viewport->next &&
-        !strcmp(skin_viewport->label,VP_DEFAULT_LABEL))
+    viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
+    skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
+    label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
+    if (skin_viewport->label == VP_DEFAULT_LABEL)
+        label = VP_DEFAULT_LABEL_STRING;
+    if (label && SKINOFFSETTOPTR(skin_buffer, viewport->next) &&
+        !strcmp(label,VP_DEFAULT_LABEL_STRING))
         refresh_mode = 0;
     
-    for (viewport = data->tree;
+    for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
          viewport;
-         viewport = viewport->next)
+         viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
     {
         /* SETUP */
-        skin_viewport = (struct skin_viewport*)viewport->data;
+        skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
         unsigned vp_refresh_mode = refresh_mode;
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
         skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour;
@@ -789,7 +824,7 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
         }
         /* render */
         if (viewport->children_count)
-            skin_render_viewport(viewport->children[0], gwps,
+            skin_render_viewport(get_child(viewport->children, 0), gwps,
                                  skin_viewport, vp_refresh_mode);
         refresh_mode = old_refresh_mode;
     }
@@ -826,7 +861,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
     struct align_pos * align = &info.align;
     bool needs_update;
     int cur_pos, start_item, max;
-    int nb_lines = viewport_get_nb_lines(viewer->vp);
+    int nb_lines = viewport_get_nb_lines(SKINOFFSETTOPTR(skin_buffer, viewer->vp));
 #if CONFIG_TUNER
     if (get_current_activity() == ACTIVITY_FM)
     {
@@ -848,7 +883,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
     if (max-start_item > nb_lines)
         max = start_item + nb_lines;
     
-    line = viewer->line;
+    line = SKINOFFSETTOPTR(skin_buffer, viewer->line);
     while (start_item < max)
     {
         linebuf[0] = '\0';
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 6f154a4..9a2c704 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -36,6 +36,7 @@
 #include "debug.h"
 #include "cuesheet.h"
 #include "replaygain.h"
+#include "core_alloc.h"
 #ifdef HAVE_LCD_CHARCELLS
 #include "hwcompat.h"
 #endif
@@ -732,18 +733,21 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
 {
     int a = lif->num_options;
     int b;
-    const char* out_text = get_token_value(gwps, lif->token, offset,
-                                           buf, buf_size, &a);            
-    if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME)
+    struct wps_token *liftoken = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->token);
+    const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a);            
+    if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
         a = (out_text && *out_text) ? 1 : 0;
     switch (lif->operand.type)
     {
         case STRING:
+        {
+            char *cmp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.text);
             if (out_text == NULL)
                 return NULL;
-            a = strcmp(out_text, lif->operand.data.text);
+            a = strcmp(out_text, cmp);
             b = 0;
             break;
+        }
         case INTEGER:
         case DECIMAL:
             b = lif->operand.data.number;
@@ -752,11 +756,12 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
         {
             char temp_buf[MAX_PATH];
             const char *outb;
-            struct wps_token *token = lif->operand.data.code->data;
+            struct skin_element *element = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.code);
+            struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), element->data);
             b = lif->num_options;
             outb = get_token_value(gwps, token, offset, temp_buf,
                                    sizeof(temp_buf), &b);            
-            if (b == -1 && lif->token->type != SKIN_TOKEN_VOLUME)
+            if (b == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
             {
                 if (!out_text || !outb)
                     return (lif->op == IF_EQUALS) ? NULL : "neq";
@@ -865,14 +870,15 @@ const char *get_token_value(struct gui_wps *gwps,
     {
         case SKIN_TOKEN_LOGICAL_IF:
         {
-            struct logical_if *lif = token->value.data;
+            struct logical_if *lif = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
             return get_lif_token_value(gwps, lif, offset, buf, buf_size);
         }
         break;
         case SKIN_TOKEN_SUBSTRING:
         {
-            struct substring *ss = token->value.data;
-            const char *token_val = get_token_value(gwps, ss->token, offset,
+            struct substring *ss = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
+            const char *token_val = get_token_value(gwps, 
+                            SKINOFFSETTOPTR(get_skin_buffer(data), ss->token), offset,
                                                     buf, buf_size, intval);
             if (token_val)
             {
@@ -909,7 +915,7 @@ const char *get_token_value(struct gui_wps *gwps,
             return &(token->value.c);
 
         case SKIN_TOKEN_STRING:
-            return (char*)token->value.data;
+            return (char*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
             
         case SKIN_TOKEN_TRANSLATEDSTRING:
             return (char*)P2STR(ID2P(token->value.i));
@@ -929,7 +935,7 @@ const char *get_token_value(struct gui_wps *gwps,
             return buf;
         case SKIN_TOKEN_LIST_ITEM_TEXT:
         {
-            struct listitem *li = (struct listitem *)token->value.data;
+            struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
             return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size);
         }
         case SKIN_TOKEN_LIST_ITEM_NUMBER:
@@ -941,7 +947,7 @@ const char *get_token_value(struct gui_wps *gwps,
             return skinlist_is_selected_item()?"s":"";
         case SKIN_TOKEN_LIST_ITEM_ICON:
         {
-            struct listitem *li = (struct listitem *)token->value.data;
+            struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
             int icon = skinlist_get_item_icon(li->offset, li->wrap);
             if (intval)
                 *intval = icon;
@@ -997,14 +1003,15 @@ const char *get_token_value(struct gui_wps *gwps,
             return buf;
 #ifdef HAVE_ALBUMART
         case SKIN_TOKEN_ALBUMART_FOUND:
-            if (data->albumart)
+            if (SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart))
             {
                 int handle = -1;
                 handle = playback_current_aa_hid(data->playback_aa_slot);
 #if CONFIG_TUNER
                 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
                 {
-                    struct dim dim = {data->albumart->width, data->albumart->height};
+                    struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
+                    struct dim dim = {aa->width, aa->height};
                     handle = radio_get_art_hid(&dim);
                 }
 #endif
@@ -1473,9 +1480,10 @@ const char *get_token_value(struct gui_wps *gwps,
             {
 #ifdef HAVE_TOUCHSCREEN
             unsigned int last_touch = touchscreen_last_touch();
-            struct touchregion_lastpress *data = token->value.data;
-            if (data->region)
-                last_touch = data->region->last_press;
+            struct touchregion_lastpress *data = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
+            struct touchregion *region = SKINOFFSETTOPTR(get_skin_buffer(data), data->region);
+            if (region)
+                last_touch = region->last_press;
 
             if (last_touch != 0xffff &&
                 TIME_BEFORE(current_tick, data->timeout + last_touch))
@@ -1805,7 +1813,7 @@ const char *get_token_value(struct gui_wps *gwps,
 #ifdef HAVE_SKIN_VARIABLES
         case SKIN_TOKEN_VAR_GETVAL:
         {
-            struct skin_var* var = token->value.data;
+            struct skin_var* var = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
             if (intval)
                 *intval = var->value;
             snprintf(buf, buf_size, "%d", var->value);
@@ -1814,8 +1822,9 @@ const char *get_token_value(struct gui_wps *gwps,
         break;
         case SKIN_TOKEN_VAR_TIMEOUT:
             {
-            struct skin_var_lastchange *data = token->value.data;
-            unsigned int last_change = data->var->last_changed;
+            struct skin_var_lastchange *data = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
+            struct skin_var* var = SKINOFFSETTOPTR(get_skin_buffer(data), data->var);
+            unsigned int last_change = var->last_changed;
 
             if (last_change != 0xffff &&
                 TIME_BEFORE(current_tick, data->timeout + last_change))
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h
deleted file mode 100644
index bfca7b7..0000000
--- a/apps/gui/skin_engine/skin_tokens.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007 Nicolas Pennequin
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
- 
-#ifndef _SKIN_TOKENS_H_
-#define _SKIN_TOKENS_H_
-
-#include <stdbool.h>
-#include "tag_table.h"
-
-struct wps_token {
-    union {
-        char c;
-        unsigned short i;
-        long l;
-        void* data;
-    } value;
-
-    enum skin_token_type type; /* enough to store the token type */
-    /* Whether the tag (e.g. track name or the album) refers the
-       current or the next song (false=current, true=next) */
-    bool next;
-};
-
-struct skin_token_list {
-    struct wps_token *token;
-    struct skin_token_list *next;
-};
-
-char* get_dir(char* buf, int buf_size, const char* path, int level);
-
-#endif
diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c
index 64c7979..a479700 100644
--- a/apps/gui/skin_engine/skin_touchsupport.c
+++ b/apps/gui/skin_engine/skin_touchsupport.c
@@ -37,11 +37,13 @@
 /** Disarms all touchregions. */
 void skin_disarm_touchregions(struct wps_data *data)
 {
-    struct skin_token_list *regions = data->touchregions;
+    struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
     while (regions)
     {
-        ((struct touchregion *)regions->token->value.data)->armed = false;
-        regions = regions->next;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
+        struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+        region->armed = false;
+        regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
     }
 }
 
@@ -56,35 +58,38 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
     short x,y;
     short vx, vy;
     int type = action_get_touchscreen_press(&x, &y);
+    struct skin_viewport *wvp;
     struct touchregion *r, *temp = NULL;
     bool repeated = (type == BUTTON_REPEAT);
     bool released = (type == BUTTON_REL);
     bool pressed = (type == BUTTON_TOUCHSCREEN);
-    struct skin_token_list *regions = data->touchregions;
+    struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
     bool needs_repeat;
 
     while (regions)
     {
-        r = (struct touchregion *)regions->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
+        r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+        wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
         /* make sure this region's viewport is visible */
-        if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
+        if (wvp->hidden_flags&VP_DRAW_HIDDEN)
         {
-            regions = regions->next;
+            regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
             continue;
         }
         if (data->touchscreen_locked && 
             (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
         {
-            regions = regions->next;
+            regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
             continue;
         }
         needs_repeat = r->press_length != PRESS;
         /* check if it's inside this viewport */
-        if (viewport_point_within_vp(&(r->wvp->vp), x, y))
+        if (viewport_point_within_vp(&(wvp->vp), x, y))
         {   /* reposition the touch inside the viewport since touchregions
              * are relative to a preceding viewport */
-            vx = x - r->wvp->vp.x;
-            vy = y - r->wvp->vp.y;
+            vx = x - wvp->vp.x;
+            vy = y - wvp->vp.y;
             /* now see if the point is inside this region */
             if (vx >= r->x && vx < r->x+r->width &&
                 vy >= r->y && vy < r->y+r->height)
@@ -127,7 +132,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
                 }
             }
         }
-        regions = regions->next;
+        regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
     }
 
     /* On release, all regions are disarmed. */
@@ -214,7 +219,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
                 {
                     case F_T_CUSTOM:
                         s->custom_setting
-                            ->load_from_cfg(s->setting, data->value.text);
+                            ->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
                         break;                          
                     case F_T_INT:
                     case F_T_UINT:
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index ed09ad0..794a587 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -25,6 +25,9 @@
 #ifndef _WPS_ENGINE_INTERNALS_
 #define _WPS_ENGINE_INTERNALS_
 
+#include "tag_table.h"
+#include "skin_parser.h"
+#include "core_alloc.h"
 
 /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds
    (possibly with a decimal fraction) but stored as integer values.
@@ -33,52 +36,48 @@
 #define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */
 #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */
 
-#include "skin_tokens.h"
-#include "tag_table.h"
-#include "skin_parser.h"
-
-
 /* TODO: sort this mess out */
 
 #include "screen_access.h"
 #include "statusbar.h"
 #include "metadata.h"
 
-/* alignments */
-#define WPS_ALIGN_RIGHT 32
-#define WPS_ALIGN_CENTER 64
-#define WPS_ALIGN_LEFT 128
-
 
 #define TOKEN_VALUE_ONLY 0x0DEADC0D
 
-#ifdef HAVE_ALBUMART
-
-/* albumart definitions */
-#define WPS_ALBUMART_NONE           0      /* WPS does not contain AA tag */
-#define WPS_ALBUMART_CHECK          1      /* WPS contains AA conditional tag */
-#define WPS_ALBUMART_LOAD           2      /* WPS contains AA tag */
+/* wps_data*/
+struct wps_token {
+    union {
+        char c;
+        unsigned short i;
+        long l;
+        OFFSETTYPE(void*) data;
+    } value;
+
+    enum skin_token_type type; /* enough to store the token type */
+    /* Whether the tag (e.g. track name or the album) refers the
+       current or the next song (false=current, true=next) */
+    bool next;
+};
 
-#define WPS_ALBUMART_ALIGN_RIGHT    1    /* x align:   right */
-#define WPS_ALBUMART_ALIGN_CENTER   2    /* x/y align: center */
-#define WPS_ALBUMART_ALIGN_LEFT     4    /* x align:   left */
-#define WPS_ALBUMART_ALIGN_TOP      1    /* y align:   top */
-#define WPS_ALBUMART_ALIGN_BOTTOM   4    /* y align:   bottom */
+char* get_dir(char* buf, int buf_size, const char* path, int level);
 
-#endif /* HAVE_ALBUMART */
 
-/* wps_data*/
+struct skin_token_list {
+    OFFSETTYPE(struct wps_token *) token;
+    OFFSETTYPE(struct skin_token_list *) next;
+};
 
 #ifdef HAVE_LCD_BITMAP
 struct gui_img {
-    struct viewport* vp;    /* The viewport to display this image in */
+    OFFSETTYPE(struct viewport*) vp;    /* The viewport to display this image in */
     short int x;                  /* x-pos */
     short int y;                  /* y-pos */
     short int num_subimages;      /* number of sub-images */
     short int subimage_height;    /* height of each sub-image */
     struct bitmap bm;
     int buflib_handle;
-    const char *label;
+    OFFSETTYPE(char*) label;
     bool loaded;            /* load state */
     bool always_display;    /* not using the preload/display mechanism */
     int display;
@@ -86,15 +85,15 @@ struct gui_img {
 };
 
 struct image_display {
-    const char *label;
+    OFFSETTYPE(char*) label;
     int subimage;
-    struct wps_token *token; /* the token to get the subimage number from */
+    OFFSETTYPE(struct wps_token*) token; /* the token to get the subimage number from */
     int offset; /* offset into the bitmap strip to start */
 };
 
 struct progressbar {
     enum skin_token_type type;
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     /* regular pb */
     short x;
     /* >=0: explicitly set in the tag -> y-coord within the viewport
@@ -105,14 +104,14 @@ struct progressbar {
     short height;
     bool  follow_lang_direction;
     
-    struct gui_img *image;
+    OFFSETTYPE(struct gui_img *) image;
     
     bool invert_fill_direction;
     bool nofill;
     bool nobar;
-    struct gui_img *slider;
+    OFFSETTYPE(struct gui_img *) slider;
     bool horizontal;
-    struct gui_img *backdrop;
+    OFFSETTYPE(struct gui_img *) backdrop;
 };
 #endif
 
@@ -125,35 +124,11 @@ struct align_pos {
 };
 
 #ifdef HAVE_LCD_BITMAP
-
-#define MAX_IMAGES (26*2) /* a-z and A-Z */
-#define MAX_PROGRESSBARS 3
-
-/* The image buffer is big enough to store one full-screen native bitmap,
-   plus two full-screen mono bitmaps. */
-
-#define WPS_MAX_VIEWPORTS   24
-#define WPS_MAX_LINES       ((LCD_HEIGHT/5+1) * 2)
-#define WPS_MAX_SUBLINES    (WPS_MAX_LINES*3)
 #define WPS_MAX_TOKENS      1150
-#define WPS_MAX_STRINGS     128
-#define STRING_BUFFER_SIZE  1024
-#define WPS_MAX_COND_LEVEL  10
-
 #else
-
-#define WPS_MAX_VIEWPORTS   2
-#define WPS_MAX_LINES       2
-#define WPS_MAX_SUBLINES    12
 #define WPS_MAX_TOKENS      64
-#define WPS_MAX_STRINGS     32
-#define STRING_BUFFER_SIZE  64
-#define WPS_MAX_COND_LEVEL  5
-
 #endif
 
-#define SUBLINE_RESET -1
-
 enum wps_parse_error {
     PARSE_OK,
     PARSE_FAIL_UNCLOSED_COND,
@@ -176,12 +151,13 @@ struct gradient_config {
 #define VP_DRAW_WASHIDDEN   0x4
 /* these are never drawn, nor cleared, i.e. just ignored */
 #define VP_NEVER_VISIBLE    0x8
-#define VP_DEFAULT_LABEL    "|"
+#define VP_DEFAULT_LABEL    -200
+#define VP_DEFAULT_LABEL_STRING "|"
 struct skin_viewport {
     struct viewport vp;   /* The LCD viewport struct */
     char hidden_flags;
     bool is_infovp;
-    char* label;
+    OFFSETTYPE(char*) label;
     int   parsed_fontid;
 #if LCD_DEPTH > 1
     unsigned start_fgcolour;
@@ -192,14 +168,14 @@ struct skin_viewport {
 #endif
 };
 struct viewport_colour {
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     unsigned colour;
 };
 
 #ifdef HAVE_TOUCHSCREEN
 struct touchregion {
-    char* label;            /* label to identify this region */
-    struct skin_viewport* wvp;/* The viewport this region is in */
+    OFFSETTYPE(char*) label;            /* label to identify this region */
+    OFFSETTYPE(struct skin_viewport*) wvp;/* The viewport this region is in */
     short int x;             /* x-pos */
     short int y;             /* y-pos */
     short int width;         /* width */
@@ -219,7 +195,7 @@ struct touchregion {
             const struct settings_list *setting; /* setting being controlled */
             union {         /* Value to set the setting to for ACTION_SETTING_SET */
                 int number;
-                char* text;
+                OFFSETTYPE(char*) text;
             } value;
         } setting_data;
         int   value;
@@ -230,20 +206,32 @@ struct touchregion {
 
 
 struct touchregion_lastpress {
-    struct touchregion *region;
+    OFFSETTYPE(struct touchregion *) region;
     long timeout;
 };
 #endif
 
 struct playlistviewer {
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     bool show_icons;
     int start_offset;
-    struct skin_element *line;
+    OFFSETTYPE(struct skin_element *) line;
 };
 
 
 #ifdef HAVE_ALBUMART
+
+/* albumart definitions */
+#define WPS_ALBUMART_NONE           0      /* WPS does not contain AA tag */
+#define WPS_ALBUMART_CHECK          1      /* WPS contains AA conditional tag */
+#define WPS_ALBUMART_LOAD           2      /* WPS contains AA tag */
+
+#define WPS_ALBUMART_ALIGN_RIGHT    1    /* x align:   right */
+#define WPS_ALBUMART_ALIGN_CENTER   2    /* x/y align: center */
+#define WPS_ALBUMART_ALIGN_LEFT     4    /* x align:   left */
+#define WPS_ALBUMART_ALIGN_TOP      1    /* y align:   top */
+#define WPS_ALBUMART_ALIGN_BOTTOM   4    /* y align:   bottom */
+
 struct skin_albumart {
     /* Album art support */
     int x;
@@ -255,7 +243,7 @@ struct skin_albumart {
     unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */
     unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */
     
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     int draw_handle;
 };
 #endif
@@ -272,11 +260,11 @@ struct line_alternator {
 
 struct conditional {
     int last_value;
-    struct wps_token *token;
+    OFFSETTYPE(struct wps_token *) token;
 };
 
 struct logical_if {
-    struct wps_token *token;
+    OFFSETTYPE(struct wps_token *) token;
     enum {
         IF_EQUALS, /* == */
         IF_NOTEQUALS, /* != */
@@ -292,7 +280,7 @@ struct logical_if {
 struct substring {
     int start;
     int length;
-    struct wps_token *token;
+    OFFSETTYPE(struct wps_token *) token;
 };
 
 struct listitem {
@@ -302,16 +290,16 @@ struct listitem {
 
 #ifdef HAVE_SKIN_VARIABLES
 struct skin_var {
-    const char *label;
+    OFFSETTYPE(const char *) label;
     int value;
     long last_changed;
 };
 struct skin_var_lastchange {
-    struct skin_var *var;
+    OFFSETTYPE(struct skin_var *) var;
     long timeout;
 };
 struct skin_var_changer {
-    struct skin_var *var;
+    OFFSETTYPE(struct skin_var *) var;
     int newval;
     bool direct; /* true to make val=newval, false for val += newval */
     int max;
@@ -323,30 +311,29 @@ struct skin_var_changer {
    viewable content of a wps */
 struct wps_data
 {
-    struct skin_element *tree;
+    int buflib_handle;
+
+    OFFSETTYPE(struct skin_element *) tree;
 #ifdef HAVE_LCD_BITMAP
-    struct skin_token_list *images;
-    int *font_ids;
+    OFFSETTYPE(struct skin_token_list *) images;
+    OFFSETTYPE(int *) font_ids;
     int font_count;
 #endif
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-    struct {
-        char *backdrop;
-        int backdrop_id;
-    };
+    int backdrop_id;
 #endif
 
 #ifdef HAVE_TOUCHSCREEN
-    struct skin_token_list *touchregions;
+    OFFSETTYPE(struct skin_token_list *) touchregions;
     bool touchscreen_locked;
 #endif
 #ifdef HAVE_ALBUMART
-    struct skin_albumart *albumart;
+    OFFSETTYPE(struct skin_albumart *) albumart;
     int    playback_aa_slot;
 #endif
 
 #ifdef HAVE_SKIN_VARIABLES
-    struct skin_token_list *skinvars;
+    OFFSETTYPE(struct skin_token_list *) skinvars;
 #endif
 
 #ifdef HAVE_LCD_BITMAP
@@ -360,6 +347,13 @@ struct wps_data
     bool wps_loaded;
 };
 
+static inline char* get_skin_buffer(struct wps_data* data)
+{
+    if (data->buflib_handle >= 0)
+        return core_get_data(data->buflib_handle);
+    return NULL;
+}
+
 /* wps_data end */
 
 /* wps_state
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index f79672c..960cf67 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -87,8 +87,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
         /* hide the sb's default viewport because it has nasty effect with stuff
         * not part of the statusbar,
         * hence .sbs's without any other vps are unsupported*/
-        struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data);
-        struct skin_element *next_vp = data->tree->next;
+        struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
+        struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree);
+        struct skin_element *next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next);
         
         if (vp)
         {
@@ -105,9 +106,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
     return 1;
 }
 
-static char *infovp_label[NB_SCREENS];
-static char *oldinfovp_label[NB_SCREENS];
-void sb_set_info_vp(enum screen_type screen, char *label)
+static OFFSETTYPE(char*) infovp_label[NB_SCREENS];
+static OFFSETTYPE(char*) oldinfovp_label[NB_SCREENS];
+void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label)
 {
     infovp_label[screen] = label;
 }
@@ -116,15 +117,19 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
 {
     struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
     struct skin_viewport *vp = NULL;
+    char *label;
     if (oldinfovp_label[screen] &&
-        strcmp(oldinfovp_label[screen], infovp_label[screen]))
+        (oldinfovp_label[screen] != infovp_label[screen]))
     {
         /* UI viewport changed, so force a redraw */
         oldinfovp_label[screen] = infovp_label[screen];
         viewportmanager_theme_enable(screen, false, NULL);
         viewportmanager_theme_undo(screen, true);
     }
-    vp = skin_find_item(infovp_label[screen], SKIN_FIND_UIVP, data);
+    label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]);
+    if (infovp_label[screen] == VP_DEFAULT_LABEL)
+        label = VP_DEFAULT_LABEL_STRING;
+    vp = skin_find_item(label, SKIN_FIND_UIVP, data);
     if (!vp)
         return NULL;
     if (vp->parsed_fontid == 1)
@@ -270,7 +275,7 @@ void sb_skin_init(void)
 {
     FOR_NB_SCREENS(i)
     {
-        oldinfovp_label[i] = NULL;
+        oldinfovp_label[i] = VP_DEFAULT_LABEL;
     }
 }
 
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index bfd8193..ac12dfa 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -36,7 +36,7 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
 
 char* sb_create_from_settings(enum screen_type screen);
 void sb_skin_init(void) INIT_ATTR;
-void sb_set_info_vp(enum screen_type screen, char *label);
+void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label);
 struct viewport *sb_skin_get_info_vp(enum screen_type screen);
 void sb_skin_update(enum screen_type screen, bool force);
 
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 6486e42..97c945d 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -667,7 +667,7 @@ static void gwps_enter_wps(void)
 #if LCD_DEPTH > 1
         if (display->depth > 1)
         {
-            struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, 
+            struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, 
                                                        SKIN_FIND_VP, gwps->data);
             if (svp)
             {
diff --git a/apps/lang/basque.lang b/apps/lang/basque.lang
index f0cc1ee..8a9de4b 100644
--- a/apps/lang/basque.lang
+++ b/apps/lang/basque.lang
@@ -11502,16 +11502,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Azalaren RAM erabilera:"
+    *: ""
   </dest>
   <voice>
-    *: "Azalaren RAM erabilera:"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/bulgarian.lang b/apps/lang/bulgarian.lang
index ad88cd7..257389c 100644
--- a/apps/lang/bulgarian.lang
+++ b/apps/lang/bulgarian.lang
@@ -12255,16 +12255,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Използвана RAM от скина:"
+    *: ""
   </dest>
   <voice>
-    *: "Използвана RAM от скина"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/catala.lang b/apps/lang/catala.lang
index e4abf58..aabcb93 100644
--- a/apps/lang/catala.lang
+++ b/apps/lang/catala.lang
@@ -11494,16 +11494,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Ús de RAM per part del tema:"
+    *: ""
   </dest>
   <voice>
-    *: "Ús de RAM per part del tema"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/chinese-simp.lang b/apps/lang/chinese-simp.lang
index fb0408d..7319071 100644
--- a/apps/lang/chinese-simp.lang
+++ b/apps/lang/chinese-simp.lang
@@ -11821,16 +11821,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Skin RAM usage:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/czech.lang b/apps/lang/czech.lang
index 3d9557d..00a89b8 100644
--- a/apps/lang/czech.lang
+++ b/apps/lang/czech.lang
@@ -11504,16 +11504,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Využití RAM pro skiny:"
+    *: ""
   </dest>
   <voice>
-    *: "Využití RAM pro skiny"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/dansk.lang b/apps/lang/dansk.lang
index 2c89ccd..d99cbc9 100644
--- a/apps/lang/dansk.lang
+++ b/apps/lang/dansk.lang
@@ -11446,16 +11446,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Temas RAM-forbrug:"
+    *: ""
   </dest>
   <voice>
-    *: "Temas RAM-forbrug"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang
index ae7867b..d565eff 100644
--- a/apps/lang/deutsch.lang
+++ b/apps/lang/deutsch.lang
@@ -11445,16 +11445,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Themen-Speicher:"
+    *: ""
   </dest>
   <voice>
-    *: "Themen-Speicher"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/english-us.lang b/apps/lang/english-us.lang
index 9a7c878..16af129 100644
--- a/apps/lang/english-us.lang
+++ b/apps/lang/english-us.lang
@@ -11500,16 +11500,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Skin RAM usage:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 5a59473..796417d 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -11587,16 +11587,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Skin RAM usage:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/espanol.lang b/apps/lang/espanol.lang
index d1b4844..f12fb2e 100644
--- a/apps/lang/espanol.lang
+++ b/apps/lang/espanol.lang
@@ -11816,16 +11816,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Uso de RAM de la piel:"
+    *: ""
   </dest>
   <voice>
-    *: "Uso de RAM de la piel"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/finnish.lang b/apps/lang/finnish.lang
index a2ab551..0855a5f 100644
--- a/apps/lang/finnish.lang
+++ b/apps/lang/finnish.lang
@@ -11383,16 +11383,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Nahan käyttämä RAM-muisti:"
+    *: ""
   </dest>
   <voice>
-    *: "Nahan käyttämä RAM-muisti"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/francais.lang b/apps/lang/francais.lang
index ff94abf..9ad6e92 100644
--- a/apps/lang/francais.lang
+++ b/apps/lang/francais.lang
@@ -11528,16 +11528,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Tampon du thème:"
+    *: ""
   </dest>
   <voice>
-    *: "Tampon du thème utilisé"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/galego.lang b/apps/lang/galego.lang
index 4d390a3..a137f68 100644
--- a/apps/lang/galego.lang
+++ b/apps/lang/galego.lang
@@ -10883,16 +10883,16 @@ ipod*,iaudiox5,iaudiom5,iriverh10,iriverh10_5gb,sansae200*,sansac200*,gigabeat*,
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Uso de RAM pola skin:"
+    *: ""
   </dest>
   <voice>
-    *: "Uso de RAM pola skin"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/hebrew.lang b/apps/lang/hebrew.lang
index 30ce32f..100a5f6 100644
--- a/apps/lang/hebrew.lang
+++ b/apps/lang/hebrew.lang
@@ -11509,16 +11509,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Skin RAM usage:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/hrvatski.lang b/apps/lang/hrvatski.lang
index cc45c15..1dbfc62 100644
--- a/apps/lang/hrvatski.lang
+++ b/apps/lang/hrvatski.lang
@@ -11503,16 +11503,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Korištenje RAM-a presvlake:"
+    *: ""
   </dest>
   <voice>
-    *: "Korištenje RAM-a presvlake"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/italiano.lang b/apps/lang/italiano.lang
index 0450f22..ddb1803 100644
--- a/apps/lang/italiano.lang
+++ b/apps/lang/italiano.lang
@@ -11504,16 +11504,16 @@ desc: deprecated
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "RAM usata per Skin:"
+    *: ""
   </dest>
   <voice>
-    *: "RAM usata per Skin"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/japanese.lang b/apps/lang/japanese.lang
index a1d6039..3a62826 100644
--- a/apps/lang/japanese.lang
+++ b/apps/lang/japanese.lang
@@ -11509,16 +11509,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "スキンのRAM使用量:"
+    *: ""
   </dest>
   <voice>
-    *: "スキンのRAM使用量"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/latviesu.lang b/apps/lang/latviesu.lang
index 866820d..0a46088 100644
--- a/apps/lang/latviesu.lang
+++ b/apps/lang/latviesu.lang
@@ -11505,16 +11505,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Ādas RAM izl.:"
+    *: ""
   </dest>
   <voice>
-    *: "aadas ram izlietojums"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/magyar.lang b/apps/lang/magyar.lang
index e18fbe4..a12de09 100644
--- a/apps/lang/magyar.lang
+++ b/apps/lang/magyar.lang
@@ -11366,16 +11366,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Téma RAM használat:"
+    *: ""
   </dest>
   <voice>
-    *: "Téma RAM használat"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/nederlands.lang b/apps/lang/nederlands.lang
index 76cd861..689b410 100644
--- a/apps/lang/nederlands.lang
+++ b/apps/lang/nederlands.lang
@@ -11852,16 +11852,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Uitzicht RAM gebruik:"
+    *: ""
   </dest>
   <voice>
-    *: "Uitzicht RAM gebruik"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/polski.lang b/apps/lang/polski.lang
index c68484f..8baa93d 100644
--- a/apps/lang/polski.lang
+++ b/apps/lang/polski.lang
@@ -11426,16 +11426,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Pamięć zajmowana przez styl:"
+    *: ""
   </dest>
   <voice>
-    *: "Pamięć zajmowana przez styl"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/portugues-brasileiro.lang b/apps/lang/portugues-brasileiro.lang
index e708e93..43bd38e 100644
--- a/apps/lang/portugues-brasileiro.lang
+++ b/apps/lang/portugues-brasileiro.lang
@@ -11501,16 +11501,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Uso de RAM do Skin:"
+    *: ""
   </dest>
   <voice>
-    *: "Uso de RAM do Skin"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/portugues.lang b/apps/lang/portugues.lang
index c980859..fde14e8 100644
--- a/apps/lang/portugues.lang
+++ b/apps/lang/portugues.lang
@@ -11679,16 +11679,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Uso de RAM do Visual:"
+    *: ""
   </dest>
   <voice>
-    *: "Uso de RAM do Visual"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/romaneste.lang b/apps/lang/romaneste.lang
index 169df41..8fcb4f8 100644
--- a/apps/lang/romaneste.lang
+++ b/apps/lang/romaneste.lang
@@ -12501,16 +12501,16 @@
 
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Utilizare RAM de către skin:"
+    *: ""
   </dest>
   <voice>
-    *: "Utilizare RAM de către skin:"
+    *: ""
   </voice>
 </phrase>
 
diff --git a/apps/lang/russian.lang b/apps/lang/russian.lang
index be67c92..7cd280c 100644
--- a/apps/lang/russian.lang
+++ b/apps/lang/russian.lang
@@ -12219,16 +12219,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "RAM для темы:"
+    *: ""
   </dest>
   <voice>
-    *: "RAM для темы"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/slovak.lang b/apps/lang/slovak.lang
index 8b34e73..0bb4b46 100644
--- a/apps/lang/slovak.lang
+++ b/apps/lang/slovak.lang
@@ -11500,16 +11500,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Pamäť Ram využitá vzhľadom"
+    *: ""
   </dest>
   <voice>
-    *: "Pamäť RAM využitá vzhľadom"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/slovenscina.lang b/apps/lang/slovenscina.lang
index a40ba3a..546eb86 100644
--- a/apps/lang/slovenscina.lang
+++ b/apps/lang/slovenscina.lang
@@ -9764,16 +9764,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Skin RAM usage:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/srpski.lang b/apps/lang/srpski.lang
index 0f70707..8d5b311 100644
--- a/apps/lang/srpski.lang
+++ b/apps/lang/srpski.lang
@@ -11784,16 +11784,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Потрошња RAM за скинове:"
+    *: ""
   </dest>
   <voice>
-    *: "Потрошња RAM за скинове"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/svenska.lang b/apps/lang/svenska.lang
index a154e00..c0b1b04 100644
--- a/apps/lang/svenska.lang
+++ b/apps/lang/svenska.lang
@@ -11506,16 +11506,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Tema:"
+    *: ""
   </dest>
   <voice>
-    *: "Tema"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/tagalog.lang b/apps/lang/tagalog.lang
index 7547954..51d8e91 100644
--- a/apps/lang/tagalog.lang
+++ b/apps/lang/tagalog.lang
@@ -11394,16 +11394,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Skin RAM usage:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/thai.lang b/apps/lang/thai.lang
index fd2d698..e0079ac 100644
--- a/apps/lang/thai.lang
+++ b/apps/lang/thai.lang
@@ -11342,16 +11342,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "หน่วยความจำหน้ากาก:"
+    *: ""
   </dest>
   <voice>
-    *: "Skin RAM usage"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/lang/walon.lang b/apps/lang/walon.lang
index 0f9b508..ab3c842 100644
--- a/apps/lang/walon.lang
+++ b/apps/lang/walon.lang
@@ -11505,16 +11505,16 @@
 </phrase>
 <phrase>
   id: LANG_SKIN_RAM_USAGE
-  desc: how much RAM the skins are using
+  desc: deprecated
   user: core
   <source>
-    *: "Skin RAM usage:"
+    *: ""
   </source>
   <dest>
-    *: "Memwere eployeye pol pea:"
+    *: ""
   </dest>
   <voice>
-    *: "Memwere eployeye pol pea"
+    *: ""
   </voice>
 </phrase>
 <phrase>
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
index 7f8a56e..8053bf0 100644
--- a/apps/menus/main_menu.c
+++ b/apps/menus/main_menu.c
@@ -147,9 +147,6 @@ enum infoscreenorder
     INFO_DISK1, /* capacity or internal capacity/free on hotswap */
     INFO_DISK2, /* free space or external capacity/free on hotswap */
     INFO_BUFFER,
-#ifndef APPLICATION
-    INFO_SKIN_USAGE, /* ram usage of the skins */
-#endif
     INFO_VERSION,
     INFO_COUNT
 };
@@ -159,7 +156,7 @@ static const char* info_getname(int selected_item, void *data,
 {
     struct info_data *info = (struct info_data*)data;
     char s1[32];
-#if defined(HAVE_MULTIVOLUME) || !defined(APPLICATION)
+#if defined(HAVE_MULTIVOLUME)
     char s2[32];
 #endif
     if (info->new_data)
@@ -246,14 +243,6 @@ static const char* info_getname(int selected_item, void *data,
             snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
 #endif
             break;
-#ifndef APPLICATION
-        case INFO_SKIN_USAGE:
-            output_dyn_value(s1, sizeof s1, skin_buffer_usage(), byte_units, true);
-            output_dyn_value(s2, sizeof s2, skin_buffer_usage()
-                                            +skin_buffer_freespace(), byte_units, true);
-            snprintf(buffer, buffer_len, "%s %s / %s", str(LANG_SKIN_RAM_USAGE), s1, s2);
-            break;
-#endif
     }
     return buffer;
 }
@@ -334,12 +323,6 @@ static int info_speak_item(int selected_item, void * data)
             output_dyn_value(NULL, 0, info->size, kbyte_units, true);
 #endif
             break;
-#ifndef APPLICATION
-        case INFO_SKIN_USAGE:
-            talk_id(LANG_SKIN_RAM_USAGE, false);
-            output_dyn_value(NULL, 0, skin_buffer_usage(), byte_units, true);
-            break;
-#endif
             
     }
     return 0;
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c
index 43f18cd..4cbabbc 100644
--- a/apps/recorder/albumart.c
+++ b/apps/recorder/albumart.c
@@ -305,7 +305,7 @@ void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear)
         return;
 
     struct wps_data *data = gwps->data;
-    struct skin_albumart *aa = data->albumart;
+    struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
 
     if (!aa)
         return;
diff --git a/lib/skin_parser/skin_buffer.c b/lib/skin_parser/skin_buffer.c
index 5a9d446..b7939eb 100644
--- a/lib/skin_parser/skin_buffer.c
+++ b/lib/skin_parser/skin_buffer.c
@@ -60,6 +60,18 @@
 static size_t buf_size;
 static unsigned char *buffer_start = NULL;
 static unsigned char *buffer_front = NULL;
+
+long skin_buffer_to_offset(void *pointer)
+{
+    return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start;
+}
+
+void* skin_buffer_from_offset(long offset)
+{
+    return offset < 0 ? NULL : buffer_start + offset;
+}
+#else
+#error needs fixing
 #endif
 
 #ifdef USE_HOST_MALLOC
@@ -147,16 +159,4 @@ size_t skin_buffer_freespace(void)
 {
     return buf_size - skin_buffer_usage();
 }
-
-static unsigned char *saved_buffer_pos = NULL;
-void skin_buffer_save_position(void)
-{
-    saved_buffer_pos = buffer_front;
-}
-    
-void skin_buffer_restore_position(void)
-{
-    if (saved_buffer_pos)
-        buffer_front = saved_buffer_pos;
-}
 #endif
diff --git a/lib/skin_parser/skin_buffer.h b/lib/skin_parser/skin_buffer.h
index b2ed34e..f19b4f9 100644
--- a/lib/skin_parser/skin_buffer.h
+++ b/lib/skin_parser/skin_buffer.h
@@ -28,6 +28,9 @@
 void skin_buffer_init(char* buffer, size_t size);
 /* Allocate size bytes from the buffer */
 
+long skin_buffer_to_offset(void *pointer);
+void* skin_buffer_from_offset(long offset);
+
 /* #define DEBUG_SKIN_ALLOCATIONS */
 
 #ifdef DEBUG_SKIN_ALLOCATIONS 
@@ -44,7 +47,4 @@ void* skin_buffer_alloc(size_t size);
 size_t skin_buffer_usage(void);
 size_t skin_buffer_freespace(void);
 
-/* save and restore a buffer position incase a skin fails to load */
-void skin_buffer_save_position(void);
-void skin_buffer_restore_position(void);
 #endif
diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c
index 52f9127..ecf238f 100644
--- a/lib/skin_parser/skin_debug.c
+++ b/lib/skin_parser/skin_debug.c
@@ -31,6 +31,7 @@
 int debug_indent_level = 0;
 extern int skin_line;
 extern char* skin_start;
+extern char* skin_buffer;
 
 /* Global error variables */
 int error_line;
@@ -38,6 +39,14 @@ int error_col;
 const char *error_line_start;
 char* error_message;
 
+
+static inline struct skin_element*
+get_child(OFFSETTYPE(struct skin_element**) children, int child)
+{
+    struct skin_element **kids = SKINOFFSETTOPTR(skin_buffer, children);
+    return kids[child];
+}
+
 /* Debugging functions */
 void skin_error(enum skin_errorcode error, const char* cursor)
 {
@@ -144,14 +153,14 @@ void skin_debug_tree(struct skin_element* root)
             printf("{ Viewport \n");
 
             debug_indent_level++;
-            skin_debug_tree(current->children[0]);
+            skin_debug_tree(get_child(current->children, 0));
             debug_indent_level--;
 
             printf("}");
             break;
 
         case TEXT:
-            text = current->data;
+            text = SKINOFFSETTOPTR(skin_buffer, current->data);
             printf("* Plain text on line %d: \"%s\"\n", current->line, text);
             break;
 
@@ -166,7 +175,7 @@ void skin_debug_tree(struct skin_element* root)
                        current->tag->name,
                        current->line, current->params_count);
                 debug_indent_level++;
-                skin_debug_params(current->params_count, current->params);
+                skin_debug_params(current->params_count, SKINOFFSETTOPTR(skin_buffer, current->params));
                 debug_indent_level--;
                 skin_debug_indent();
                 printf(")\n");
@@ -185,7 +194,7 @@ void skin_debug_tree(struct skin_element* root)
             debug_indent_level++;
             for(i = 0; i < current->children_count; i++)
             {
-                skin_debug_tree(current->children[i]);
+                skin_debug_tree(get_child(current->children, i));
             }
             debug_indent_level--;
 
@@ -203,7 +212,7 @@ void skin_debug_tree(struct skin_element* root)
                 skin_debug_indent();
                 printf("[ Enumeration %d\n", i);
                 debug_indent_level++;
-                skin_debug_tree(current->children[i]);
+                skin_debug_tree(get_child(current->children, i));
                 debug_indent_level--;
                 skin_debug_indent();
                 printf("]\n");
@@ -221,7 +230,7 @@ void skin_debug_tree(struct skin_element* root)
 
             debug_indent_level++;
             if (current->children)
-                skin_debug_tree(current->children[0]);
+                skin_debug_tree(get_child(current->children, 0));
             debug_indent_level--;
 
             skin_debug_indent();
@@ -229,7 +238,7 @@ void skin_debug_tree(struct skin_element* root)
             break;
         }
 
-        current = current->next;
+        current = SKINOFFSETTOPTR(skin_buffer, current->next);
     }
 
 }
@@ -248,7 +257,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
             break;
 
         case STRING:
-            printf("string: \"%s\"", params[i].data.text);
+            printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text));
             break;
 
         case INTEGER:
@@ -263,7 +272,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
         case CODE:
             printf("Skin Code: \n");
             debug_indent_level++;
-            skin_debug_tree(params[i].data.code);
+            skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code));
             debug_indent_level--;
             skin_debug_indent();
             break;
diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c
index 2612cc8..21e445b 100644
--- a/lib/skin_parser/skin_parser.c
+++ b/lib/skin_parser/skin_parser.c
@@ -37,8 +37,6 @@ int skin_line = 0;
 char* skin_start = 0;
 int viewport_line = 0;
 
-static int tag_recursion_level = 0;
-
 #ifdef ROCKBOX
 static skin_callback callback = NULL;
 static void* callback_data;
@@ -81,8 +79,6 @@ struct skin_element* skin_parse(const char* document)
     struct skin_element* root = NULL;
     struct skin_element* last = NULL;
 
-    struct skin_element** to_write = 0;
-
     const char* cursor = document; /*Keeps track of location in the document*/
     
     skin_line = 1;
@@ -93,14 +89,18 @@ struct skin_element* skin_parse(const char* document)
 
     while(*cursor != '\0')
     {
+        struct skin_element* tree = skin_parse_viewport(&cursor);
         if(!root)
-            to_write = &root;
+        {
+            root = tree;
+            last = root;
+        }
         else
-            to_write = &(last->next);
-
+        {
+            last->next = skin_buffer_to_offset(tree);
+            last = tree;
+        }
 
-        *to_write = skin_parse_viewport(&cursor);
-        last = *to_write;
         if(!last)
         {
             skin_free_tree(root); /* Clearing any memory already used */
@@ -108,8 +108,8 @@ struct skin_element* skin_parse(const char* document)
         }
 
         /* Making sure last is at the end */
-        while(last->next)
-            last = last->next;
+        while(last->next >= 0)
+            last = skin_buffer_from_offset(last->next);
 
     }
     return root;
@@ -121,8 +121,6 @@ static struct skin_element* skin_parse_viewport(const char** document)
     struct skin_element* root = NULL;
     struct skin_element* last = NULL;
     struct skin_element* retval = NULL;
-    
-    tag_recursion_level = 0;
 
     retval = skin_alloc_element();
     if (!retval)
@@ -132,7 +130,7 @@ static struct skin_element* skin_parse_viewport(const char** document)
     retval->line = skin_line;
     viewport_line = skin_line;
 
-    struct skin_element** to_write = 0;
+    OFFSETTYPE(struct skin_element*)* children;
 
     const char* cursor = *document; /* Keeps track of location in the document */
     const char* bookmark; /* Used when we need to look ahead */
@@ -143,7 +141,10 @@ static struct skin_element* skin_parse_viewport(const char** document)
     if(check_viewport(cursor))
     {
         if (!skin_parse_tag(retval, &cursor))
+        {
+            printf("f1\n");
             return NULL;
+        }
         if(*cursor == '\n')
         {
             cursor++;
@@ -154,7 +155,10 @@ static struct skin_element* skin_parse_viewport(const char** document)
     else if (callback)
     {
         if (callback(retval, callback_data) == CALLBACK_ERROR)
+        {
+            printf("f1\n");
             return NULL;
+        }
     }
 #endif
 
@@ -165,9 +169,12 @@ static struct skin_element* skin_parse_viewport(const char** document)
         return retval;
     }
     retval->children_count = 1;
-    retval->children = skin_alloc_children(1);
-    if (!retval->children)
-        return NULL;
+    children = skin_alloc_children(1);
+    if (!children)
+        {
+            printf("f1\n");
+            return NULL;
+        }
     do
     {
 
@@ -212,15 +219,19 @@ static struct skin_element* skin_parse_viewport(const char** document)
         }
         cursor = bookmark;
 
-        if(!root)
-            to_write = &root;
-        else
-            to_write = &(last->next);
-
         if(sublines)
         {
-            *to_write = skin_parse_sublines(&cursor);
-            last = *to_write;
+            struct skin_element* out = skin_parse_sublines(&cursor);
+            if (!root)
+            {
+                root = out;
+                last = root;
+            }
+            else
+            {
+                last->next = skin_buffer_to_offset(out);
+                last = out;
+            }
             if(!last)
                 return NULL;
         }
@@ -237,15 +248,25 @@ static struct skin_element* skin_parse_viewport(const char** document)
             if (check_viewport(cursor))
                 break;
 #endif
-            *to_write = skin_parse_line(&cursor);
-            last = *to_write;
+
+            struct skin_element* out = skin_parse_line(&cursor);
+            if (!root)
+            {
+                root = out;
+                last = root;
+            }
+            else
+            {
+                last->next = skin_buffer_to_offset(out);
+                last = out;
+            }
             if(!last)
                 return NULL;
 
         }
         /* Making sure last is at the end */
-        while(last->next)
-            last = last->next;
+        while(last->next >= 0)
+            last = skin_buffer_from_offset(last->next);
 
         if(*cursor == '\n')
         {
@@ -269,7 +290,8 @@ static struct skin_element* skin_parse_viewport(const char** document)
 
     *document = cursor;
 
-    retval->children[0] = root;
+    children[0] = skin_buffer_to_offset(root);
+    retval->children = skin_buffer_to_offset(children);
     return retval;
 }
 
@@ -293,6 +315,7 @@ static struct skin_element* skin_parse_line_optional(const char** document,
     struct skin_element* root = NULL;
     struct skin_element* current = NULL;
     struct skin_element* retval = NULL;
+    OFFSETTYPE(struct skin_element*)* children = NULL;
 
     /* A wrapper for the line */
     retval = skin_alloc_element();
@@ -315,8 +338,8 @@ static struct skin_element* skin_parse_line_optional(const char** document,
 
     if(retval->children_count > 0)
     {
-        retval->children = skin_alloc_children(1);
-        if (!retval->children)
+        children = skin_alloc_children(1);
+        if (!children)
             return NULL;
     }
 
@@ -344,10 +367,11 @@ static struct skin_element* skin_parse_line_optional(const char** document,
         /* Allocating memory if necessary */
         if(root)
         {
-            current->next = skin_alloc_element();
-            if (!current->next)
+            struct skin_element *next = skin_alloc_element();
+            if (!next)
                 return NULL;
-            current = current->next;
+            current->next = skin_buffer_to_offset(next);
+            current = next;
         }
         else
         {
@@ -384,7 +408,10 @@ static struct skin_element* skin_parse_line_optional(const char** document,
     *document = cursor;
     
     if(root)
-        retval->children[0] = root;
+    {
+        children[0] = skin_buffer_to_offset(root);
+        retval->children = skin_buffer_to_offset(children);
+    }
     return retval;
 }
 
@@ -397,6 +424,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
                                                   int conditional)
 {
     struct skin_element* retval;
+    OFFSETTYPE(struct skin_element*)* children;
     const char* cursor = *document;
     int sublines = 1;
     int i;
@@ -405,7 +433,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
     if (!retval)
         return NULL;
     retval->type = LINE_ALTERNATOR;
-    retval->next = NULL;
+    retval->next = skin_buffer_to_offset(NULL);
     retval->line = skin_line;
 
     /* First we count the sublines */
@@ -449,14 +477,16 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
 
     /* ...and then we parse them */
     retval->children_count = sublines;
-    retval->children = skin_alloc_children(sublines);
-    if (!retval->children)
+    children = skin_alloc_children(sublines);
+    if (!children)
         return NULL;
 
     cursor = *document;
     for(i = 0; i < sublines; i++)
     {
-        retval->children[i] = skin_parse_line_optional(&cursor, conditional);
+        children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional));
+        if (children[i] < 0)
+            return NULL;
         skip_whitespace(&cursor);
 
         if(*cursor != MULTILINESYM && i != sublines - 1)
@@ -478,6 +508,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
     }
 #endif
     *document = cursor;
+    retval->children = skin_buffer_to_offset(children);
 
     return retval;
 }
@@ -490,13 +521,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
     char tag_name[3];
     char* tag_args;
     const struct tag_info *tag;
+    struct skin_tag_parameter* params = NULL;
 
     int num_args = 1;
     int i;
     int star = 0; /* Flag for the all-or-none option */
 
     int optional = 0;
-    tag_recursion_level++;
 
     /* Checking the tag name */
     tag_name[0] = cursor[0];
@@ -597,8 +628,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
 
     cursor = bookmark; /* Restoring the cursor */
     element->params_count = num_args;
-    element->params = skin_alloc_params(num_args, tag_recursion_level<=1);
-    if (!element->params)
+    params = skin_alloc_params(num_args);
+    if (!params)
         return 0;
 
     /* Now we have to actually parse each argument */
@@ -686,14 +717,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
         else
             type_code = *tag_args;
         /* Storing the type code */
-        element->params[i].type_code = type_code;
+        params[i].type_code = type_code;
 
         /* Checking a nullable argument for null. */
         if(*cursor == DEFAULTSYM && !isdigit(cursor[1]))
         {
             if(islower(type_code))
             {
-                element->params[i].type = DEFAULT;
+                params[i].type = DEFAULT;
                 cursor++;
             }
             else
@@ -711,8 +742,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
                 return 0;
             }
 
-            element->params[i].type = INTEGER;
-            element->params[i].data.number = scan_int(&cursor);
+            params[i].type = INTEGER;
+            params[i].data.number = scan_int(&cursor);
         }
         else if(tolower(type_code) == 'd')
         {
@@ -738,23 +769,23 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
             }
             if (have_tenth == false)
                 val *= 10;
-            element->params[i].type = DECIMAL;
-            element->params[i].data.number = val;
+            params[i].type = DECIMAL;
+            params[i].data.number = val;
         }
         else if(tolower(type_code) == 'n' ||
                 tolower(type_code) == 's' || tolower(type_code) == 'f')
         {
             /* Scanning a string argument */
-            element->params[i].type = STRING;
-            element->params[i].data.text = scan_string(&cursor);
+            params[i].type = STRING;
+            params[i].data.text = skin_buffer_to_offset(scan_string(&cursor));
 
         }
         else if(tolower(type_code) == 'c')
         {
             /* Recursively parsing a code argument */
-            element->params[i].type = CODE;
-            element->params[i].data.code = skin_parse_code_as_arg(&cursor);
-            if(!element->params[i].data.code)
+            params[i].type = CODE;
+            params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
+            if(params[i].data.code < 0)
                 return 0;
         }
         else if (tolower(type_code) == 't')
@@ -763,9 +794,9 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
             child->type = TAG;
             if (!skin_parse_tag(child, &cursor))
                 return 0;
-            child->next = NULL;
-            element->params[i].type = CODE;
-            element->params[i].data.code = child;
+            child->next = skin_buffer_to_offset(NULL);
+            params[i].type = CODE;
+            params[i].data.code = skin_buffer_to_offset(child);
         }
             
 
@@ -796,6 +827,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
             tag_args++;
         }
     }
+    element->params = skin_buffer_to_offset(params);
 
     /* Checking for a premature end */
     if(*tag_args != '\0' && !optional)
@@ -811,7 +843,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
     }
 #endif
     *document = cursor;
-    tag_recursion_level--;
 
     return 1;
 }
@@ -855,9 +886,10 @@ static int skin_parse_text(struct skin_element* element, const char** document,
     /* Copying the text into the element struct */
     element->type = TEXT;
     element->line = skin_line;
-    element->next = NULL;
-    element->data = text = skin_alloc_string(length);
-    if (!element->data)
+    element->next = skin_buffer_to_offset(NULL);
+    text = skin_alloc_string(length);
+    element->data = skin_buffer_to_offset(text);
+    if (element->data < 0)
         return 0;
     
     for(dest = 0; dest < length; dest++)
@@ -896,6 +928,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
     const char *false_branch = NULL;
     const char *conditional_end = NULL;
 #endif
+    OFFSETTYPE(struct skin_element*)* children_array = NULL;
 
     /* Some conditional tags allow for target feature checking,
      * so to handle that call the callback as usual with type == TAG
@@ -994,23 +1027,23 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
     {
         const char* emptyline= "";
         children = 1;
-        element->children = skin_alloc_children(children);
-        if (!element->children)
+        children_array = skin_alloc_children(children);
+        if (!children_array)
             return 0;
         element->children_count = children;
-        element->children[0] = skin_parse_code_as_arg(&emptyline);
+        children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline));
     }
     else
     {    
-        element->children = skin_alloc_children(children);
-        if (!element->children)
+        children_array = skin_alloc_children(children);
+        if (!children_array)
             return 0;
         element->children_count = children;
 
         for(i = 0; i < children; i++)
         {
-            element->children[i] = skin_parse_code_as_arg(&cursor);
-            if (element->children[i] == NULL)
+            children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
+            if (children_array[i] < 0)
                 return 0;
             skip_whitespace(&cursor);
 #ifdef ROCKBOX
@@ -1035,6 +1068,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
         }
     }
     *document = cursor;
+    element->children = skin_buffer_to_offset(children_array);
 
     return 1;
 }
@@ -1056,7 +1090,7 @@ static int skin_parse_comment(struct skin_element* element, const char** documen
     element->type = COMMENT;
     element->line = skin_line;
 #ifdef ROCKBOX 
-    element->data = NULL;
+    element->data = -1;
 #else    
     element->data = text = skin_alloc_string(length);
     if (!element->data)
@@ -1121,7 +1155,13 @@ static struct skin_element* skin_parse_code_as_arg(const char** document)
     else
         return skin_parse_line_optional(document, 1);
 }
-
+skinoffset ptrtoskinoffset(void* base, void* pointer, char* file, int line)
+{
+    if (pointer && ((pointer < base) || (pointer >= base + skin_buffer_usage())))
+        printf("%s:%d\n", file, line);
+    return ((pointer) ? ((void*)pointer-(void*)base) : -1);
+}
+    
 
 /* Memory management */
 struct skin_element* skin_alloc_element()
@@ -1131,10 +1171,12 @@ struct skin_element* skin_alloc_element()
     if (!retval)
         return NULL;
     retval->type = UNKNOWN;
-    retval->next = NULL;
+    retval->next = skin_buffer_to_offset(NULL);
+    retval->params = skin_buffer_to_offset(NULL);
     retval->tag = NULL;
     retval->params_count = 0;
     retval->children_count = 0;
+    retval->data = -1;
 
     return retval;
 
@@ -1144,16 +1186,8 @@ struct skin_element* skin_alloc_element()
  * enough for any tag. params should be used straight away by the callback
  * so this is safe.
  */
-struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params)
+struct skin_tag_parameter* skin_alloc_params(int count)
 {
-#ifdef ROCKBOX
-    static struct skin_tag_parameter params[MAX_TAG_PARAMS];
-    if (use_shared_params && count <= MAX_TAG_PARAMS)
-    {
-        memset(params, 0, sizeof(params));
-        return params;
-    }
-#endif
     size_t size = sizeof(struct skin_tag_parameter) * count;
     return (struct skin_tag_parameter*)skin_buffer_alloc(size);
 
@@ -1164,9 +1198,9 @@ char* skin_alloc_string(int length)
     return (char*)skin_buffer_alloc(sizeof(char) * (length + 1));
 }
 
-struct skin_element** skin_alloc_children(int count)
+OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count)
 {
-    return (struct skin_element**)
+    return (OFFSETTYPE(struct skin_element*)*)
             skin_buffer_alloc(sizeof(struct skin_element*) * count);
 }
 
diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h
index 3e06349..1bbb444 100644
--- a/lib/skin_parser/skin_parser.h
+++ b/lib/skin_parser/skin_parser.h
@@ -29,6 +29,22 @@ extern "C"
 #include <stdlib.h>
 #include <stdbool.h>
 
+
+/* Use this type and macro to convert a pointer from the
+ * skin buffer to a useable pointer */
+typedef long skinoffset;
+#define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset]))
+#define PTRTOSKINOFFSET(base, pointer) ptrtoskinoffset(base, pointer, __FILE__, __LINE__)
+/* Use this macro when declaring a variable to self-document the code.
+ * type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo )
+ * 
+ * WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont
+ * do what you expect.
+ */
+#define OFFSETTYPE(type) skinoffset
+
+skinoffset ptrtoskinoffset(void* base, void* pointer, char* file, int line);
+
 /********************************************************************
  ****** Data Structures *********************************************
  *******************************************************************/
@@ -78,8 +94,8 @@ struct skin_tag_parameter
     union
     {
         int number;
-        char* text;
-        struct skin_element* code;
+        OFFSETTYPE(char*) text;
+        OFFSETTYPE(struct skin_element*) code;
     } data;
 
     char type_code;
@@ -92,20 +108,20 @@ struct skin_tag_parameter
 struct skin_element
 {
     /* Link to the next element */
-    struct skin_element* next;
+    OFFSETTYPE(struct skin_element*) next;
     /* Pointer to an array of children */
-    struct skin_element** children;
+    OFFSETTYPE(struct skin_element**) children;
     /* Placeholder for element data
      * TEXT and COMMENT uses it for the text string
      * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage
      */
-    void* data;
+    OFFSETTYPE(void*) data;
 
     /* The tag or conditional name */
     const struct tag_info *tag;
 
     /* Pointer to an array of parameters */
-    struct skin_tag_parameter* params;
+    OFFSETTYPE(struct skin_tag_parameter*) params;
 
     /* Number of elements in the children array */
     short children_count;
@@ -140,8 +156,8 @@ struct skin_element* skin_parse(const char* document);
 #endif
 /* Memory management functions */
 struct skin_element* skin_alloc_element(void);
-struct skin_element** skin_alloc_children(int count);
-struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params);
+OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count);
+struct skin_tag_parameter* skin_alloc_params(int count);
 char* skin_alloc_string(int length);
 
 void skin_free_tree(struct skin_element* root);
diff --git a/tools/checkwps/checkwps.c b/tools/checkwps/checkwps.c
index 846dd97..ec0262b 100644
--- a/tools/checkwps/checkwps.c
+++ b/tools/checkwps/checkwps.c
@@ -37,6 +37,7 @@
 
 bool debug_wps = true;
 int wps_verbose_level = 0;
+char *skin_buffer;
 
 int errno;
 
@@ -252,8 +253,6 @@ int main(int argc, char **argv)
     struct wps_data wps={0};
     enum screen_type screen = SCREEN_MAIN;
     struct screen* wps_screen;
-    
-    char* buffer = NULL;
 
     /* No arguments -> print the help text
      * Also print the help text upon -h or --help */
@@ -278,14 +277,14 @@ int main(int argc, char **argv)
             wps_verbose_level++;
         }
     }
-    buffer = malloc(SKIN_BUFFER_SIZE);
-    if (!buffer)
+    skin_buffer = malloc(SKIN_BUFFER_SIZE);
+    if (!skin_buffer)
     {
         printf("mallloc fail!\n");
         return 1;
     }
 
-    skin_buffer_init(buffer, SKIN_BUFFER_SIZE);
+    skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
 
     /* Go through every skin that was thrown at us, error out at the first
      * flawed wps */
@@ -311,7 +310,7 @@ int main(int argc, char **argv)
 
         printf("WPS parsed OK\n\n");
         if (wps_verbose_level>2)
-            skin_debug_tree(wps.tree);
+            skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, wps.tree));
         filearg++;
     }
     return 0;
