diff --git a/pd/src/x_list.c b/pd/src/x_list.c
index 70dbdfd87e7148ed9d236b9019a73a4a6be348c0..2f7c97d3732589da473a6ba31004b62da0f9f388 100644
--- a/pd/src/x_list.c
+++ b/pd/src/x_list.c
@@ -516,6 +516,32 @@ static void *list_store_new(t_symbol *s, int argc, t_atom *argv)
     return (x);
 }
 
+static void list_store_send(t_list_store *x, t_symbol *s)
+{
+    t_atom *vec;
+    int n = x->x_alist.l_n;
+    if (!s->s_thing)
+    {
+        pd_error(x, "%s: no such object", s->s_name);
+        return;
+    }
+    ATOMS_ALLOCA(vec, n);
+    if (x->x_alist.l_npointer)
+    {
+        t_alist y;
+        alist_clone(&x->x_alist, &y, 0, n);
+        alist_toatoms(&y, vec, 0, n);
+        pd_list(s->s_thing, gensym("list"), n, vec);
+        alist_clear(&y);
+    }
+    else
+    {
+        alist_toatoms(&x->x_alist, vec, 0, n);
+        pd_list(s->s_thing, gensym("list"), n, vec);
+    }
+    ATOMS_FREEA(vec, n);
+}
+
 static void list_store_list(t_list_store *x, t_symbol *s,
     int argc, t_atom *argv)
 {
@@ -553,61 +579,131 @@ static void list_store_restore_gpointers(t_list_store *x, int offset, int count)
     }
 }
 
-static void list_store_append(t_list_store *x, t_symbol *s,
-    int argc, t_atom *argv)
+static void list_store_doinsert(t_list_store *x, t_symbol *s,
+    int argc, t_atom *argv, int index)
 {
     t_listelem *oldptr = x->x_alist.l_vec;
-
+        /* try to allocate more memory */
     if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec,
         (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec),
         (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec))))
     {
         x->x_alist.l_n = 0;
-        error("list: out of memory");
+        pd_error(0, "list: out of memory");
         return;
     }
-
-        /* fix gpointers if resizebytes() has moved the alist in memory */
+        /* fix gpointers in case resizebytes() has moved the alist in memory */
     if (x->x_alist.l_vec != oldptr && x->x_alist.l_npointer)
-        list_store_restore_gpointers(x, 0, x->x_alist.l_n);
-
-    alist_copyin(&x->x_alist, s, argc, argv, x->x_alist.l_n);
+        list_store_restore_gpointers(&x->x_alist, 0, x->x_alist.l_n);
+        /* shift existing elements after 'index' to the right */
+    if (index < x->x_alist.l_n)
+    {
+        memmove(x->x_alist.l_vec + index + argc, x->x_alist.l_vec + index,
+            (x->x_alist.l_n - index) * sizeof(*x->x_alist.l_vec));
+            /* fix gpointers because of memmove() */
+        if (x->x_alist.l_npointer)
+            list_store_restore_gpointers(&x->x_alist, index + argc, x->x_alist.l_n - index);
+    }
+        /* finally copy new elements */
+    alist_copyin(&x->x_alist, s, argc, argv, index);
     x->x_alist.l_n += argc;
 }
 
+static void list_store_insert(t_list_store *x, t_symbol *s,
+    int argc, t_atom *argv)
+{
+    if (argc > 1)
+    {
+        int index = atom_getfloat(argv);
+        if (index < 0)
+        {
+            pd_error(x, "list_store_insert: index %d out of range", index);
+            return;
+        } else if (index > x->x_alist.l_n)
+            index = x->x_alist.l_n;
+        list_store_doinsert(x, s, --argc, ++argv, index);
+    }
+}
+
+static void list_store_append(t_list_store *x, t_symbol *s,
+    int argc, t_atom *argv)
+{
+    list_store_doinsert(x, s, argc, argv, x->x_alist.l_n);
+}
+
 static void list_store_prepend(t_list_store *x, t_symbol *s,
     int argc, t_atom *argv)
 {
+    list_store_doinsert(x, s, argc, argv, 0);
+}
+
+static void list_store_delete(t_list_store *x, t_floatarg f1, t_floatarg f2)
+{
+    int i, max, index = (int)f1, n = (int)f2;
+    t_listelem *oldptr = x->x_alist.l_vec;
+    if (index < 0 || index >= x->x_alist.l_n)
+    {
+        pd_error(x, "list_store_delete: index %d out of range", index);
+        return;
+    }
+    max = x->x_alist.l_n - index;
+    if (!n)
+        n = 1; /* default */
+    else if (n < 0 || n > max)
+        n = max; /* till the end of the list */
+
+        /* unset pointers for elements which are to be deleted */
+    if (x->x_alist.l_npointer)
+    {
+        t_listelem *vec = x->x_alist.l_vec + index;
+        for (i = 0; i < n; i++)
+        {
+            if (vec[i].l_a.a_type == A_POINTER)
+            {
+                gpointer_unset(vec[i].l_a.a_w.w_gpointer);
+                x->x_alist.l_npointer--;
+            }
+        }
+    }
+        /* shift elements (after the deleted elements) to the left */
+    memmove(x->x_alist.l_vec + index, x->x_alist.l_vec + index + n,
+        (x->x_alist.l_n - index - n) * sizeof(*x->x_alist.l_vec));
+        /* shrink memory */
     if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec,
-    (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec),
-    (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec))))
+        (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec),
+        (x->x_alist.l_n - n) * sizeof(*x->x_alist.l_vec))))
     {
         x->x_alist.l_n = 0;
-        error("list: out of memory");
+        pd_error(0, "list: out of memory");
         return;
     }
-
-    memmove(x->x_alist.l_vec + argc, x->x_alist.l_vec,
-        x->x_alist.l_n * sizeof(*x->x_alist.l_vec));
-
-        /* we always have to fix gpointers because of memmove() */
     if (x->x_alist.l_npointer)
-        list_store_restore_gpointers(x, argc, x->x_alist.l_n);
-
-    alist_copyin(&x->x_alist, s, argc, argv, 0);
-    x->x_alist.l_n += argc;
+    {
+            /* fix all gpointers in case resizebytes() has moved the alist in memory */
+        if (x->x_alist.l_vec != oldptr)
+            list_store_restore_gpointers(&x->x_alist, 0, x->x_alist.l_n - n);
+        else /* only fix gpointers after index (because of of memmove()) */
+            list_store_restore_gpointers(&x->x_alist, index, x->x_alist.l_n - index - n);
+    }
+    x->x_alist.l_n -= n;
 }
 
-static void list_store_get(t_list_store *x, float f1, float f2)
+static void list_store_get(t_list_store *x, t_floatarg f1, t_floatarg f2)
 {
     t_atom *outv;
     int onset = f1, outc = f2;
-    if (onset < 0 || outc < 0)
+    if (!outc)
+        outc = 1; /* default */
+    else if (outc < 0)
     {
-        pd_error(x, "list_store_get: negative range (%d %d)", onset, outc);
-        return;
+        outc = x->x_alist.l_n - onset; /* till the end of the list */
+        if (outc <= 0) /* onset out of range */
+        {
+            outlet_bang(x->x_out2);
+            return;
+        }
     }
-    if (onset + outc > x->x_alist.l_n)
+    if (onset < 0 || (onset + outc > x->x_alist.l_n))
     {
         outlet_bang(x->x_out2);
         return;
@@ -629,6 +725,23 @@ static void list_store_get(t_list_store *x, float f1, float f2)
     ATOMS_FREEA(outv, outc);
 }
 
+static void list_store_set(t_list_store *x, t_symbol *s, int argc, t_atom *argv)
+{
+    if (argc > 1)
+    {
+        int n, max, onset = atom_getfloat(argv);
+        if (onset < 0 || onset >= x->x_alist.l_n)
+        {
+            pd_error(x, "list_store_set: index %d out of range", onset);
+            return;
+        }
+        argc--; argv++;
+        max = x->x_alist.l_n - onset;
+        n = (argc > max) ? max : argc;
+        alist_copyin(&x->x_alist, s, n, argv, onset);
+    }
+}
+
 static void list_store_free(t_list_store *x)
 {
     alist_clear(&x->x_alist);
@@ -640,12 +753,20 @@ static void list_store_setup(void)
         (t_newmethod)list_store_new, (t_method)list_store_free,
         sizeof(t_list_store), 0, A_GIMME, 0);
     class_addlist(list_store_class, list_store_list);
+    class_addmethod(list_store_class, (t_method)list_store_send,
+        gensym("send"), A_SYMBOL, 0);
     class_addmethod(list_store_class, (t_method)list_store_append,
         gensym("append"), A_GIMME, 0);
     class_addmethod(list_store_class, (t_method)list_store_prepend,
         gensym("prepend"), A_GIMME, 0);
+    class_addmethod(list_store_class, (t_method)list_store_insert,
+        gensym("insert"), A_GIMME, 0);
+    class_addmethod(list_store_class, (t_method)list_store_delete,
+        gensym("delete"), A_FLOAT, A_DEFFLOAT, 0);
     class_addmethod(list_store_class, (t_method)list_store_get,
-        gensym("get"), A_FLOAT, A_FLOAT, 0);
+        gensym("get"), A_FLOAT, A_DEFFLOAT, 0);
+    class_addmethod(list_store_class, (t_method)list_store_set,
+        gensym("set"), A_GIMME, 0);
     class_sethelpsymbol(list_store_class, &s_list);
 }
 
@@ -867,7 +988,7 @@ static void list_tosymbol_setup(void)
 
 /* ------------- list ------------------- */
 
-static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
+void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
 {
     if (!argc || argv[0].a_type != A_SYMBOL)
         newest = list_append_new(s, argc, argv);