diff --git a/library/collection/List.scala b/library/collection/List.scala
index 1f8253f13e1ed15163265a20a1e36bba01b11d71..69383585c9e9f0eff8666bfcfcc03e44f66f48a5 100644
--- a/library/collection/List.scala
+++ b/library/collection/List.scala
@@ -2,6 +2,7 @@
 
 package leon.collection
 
+import leon._
 import leon.lang._
 import leon.annotation._
 
@@ -84,6 +85,203 @@ sealed abstract class List[T] {
         t.drop(i-1)
       }
   }
+
+  def slice(from: Int, to: Int): List[T] = {
+    require(from < to && to < size && from >= 0)
+    drop(from).take(to-from)
+  }
+
+  def replace(from: T, to: T): List[T] = this match {
+    case Nil() => Nil()
+    case Cons(h, t) =>
+      val r = t.replace(from, to)
+      if (h == from) {
+        Cons(to, r)
+      } else {
+        Cons(h, r)
+      }
+  }
+
+  private def chunk0(s: Int, l: List[T], acc: List[T], res: List[List[T]], s0: Int): List[List[T]] = l match {
+    case Nil() =>
+      if (acc.size > 0) {
+        res :+ acc
+      } else {
+        res
+      }
+    case Cons(h, t) =>
+      if (s0 == 0) {
+        chunk0(s, l, Nil(), res :+ acc, s)
+      } else {
+        chunk0(s, t, acc :+ h, res, s0-1)
+      }
+  }
+
+  def chunks(s: Int): List[List[T]] = {
+    require(s > 0)
+
+    chunk0(s, this, Nil(), Nil(), s)
+  }
+
+  def zip[B](that: List[B]): List[(T, B)] = (this, that) match {
+    case (Cons(h1, t1), Cons(h2, t2)) =>
+      Cons((h1, h2), t1.zip(t2))
+    case (_) =>
+      Nil()
+  }
+
+  def -(e: T): List[T] = this match {
+    case Cons(h, t) =>
+      if (e == h) {
+        t - e
+      } else {
+        Cons(h, t - e)
+      }
+    case Nil() =>
+      Nil()
+  }
+
+  def --(that: List[T]): List[T] = this match {
+    case Cons(h, t) =>
+      if (that.contains(h)) {
+        t -- that
+      } else {
+        Cons(h, t -- that)
+      }
+    case Nil() =>
+      Nil()
+  }
+
+  def &(that: List[T]): List[T] = this match {
+    case Cons(h, t) =>
+      if (that.contains(h)) {
+        Cons(h, t & that)
+      } else {
+        t & that
+      }
+    case Nil() =>
+      Nil()
+  }
+
+  def pad(s: Int, e: T): List[T] = (this, s) match {
+    case (_, s) if s <= 0 =>
+      this
+    case (Nil(), s) =>
+      Cons(e, Nil().pad(s-1, e))
+    case (Cons(h, t), s) =>
+      Cons(h, t.pad(s-1, e))
+  }
+
+  def find(e: T): Option[Int] = this match {
+    case Nil() => None()
+    case Cons(h, t) =>
+      if (h == e) {
+        Some(0)
+      } else {
+        t.find(e) match {
+          case None()  => None()
+          case Some(i) => Some(i+1)
+        }
+      }
+  }
+
+  def lastOption: Option[T] = this match {
+    case Cons(h, t) =>
+      t.lastOption.orElse(Some(h))
+    case Nil() =>
+      None()
+  }
+
+  def firstOption: Option[T] = this match {
+    case Cons(h, t) =>
+      Some(h)
+    case Nil() =>
+      None()
+  }
+
+  def unique: List[T] = this match {
+    case Nil() => Nil()
+    case Cons(h, t) =>
+      Cons(h, t.unique - h)
+  }
+
+  def splitAt(e: T): List[List[T]] =  split(Cons(e, Nil()))
+
+  def split(seps: List[T]): List[List[T]] = this match {
+    case Cons(h, t) =>
+      if (seps.contains(h)) {
+        Cons(Nil(), t.split(seps))
+      } else {
+        val r = t.split(seps)
+        Cons(Cons(h, r.head), r.tail)
+      }
+    case Nil() =>
+      Cons(Nil(), Nil())
+  }
+
+  def count(e: T): Int = this match {
+    case Cons(h, t) =>
+      if (h == e) {
+        1 + t.count(e)
+      } else {
+        t.count(e)
+      }
+    case Nil() =>
+      0
+  }
+
+  def evenSplit: (List[T], List[T]) = {
+    val c = size/2
+    (take(c), drop(c))
+  }
+
+  def insertAt(pos: Int, l: List[T]): List[T] = {
+    if(pos < 0) {
+      insertAt(size + pos, l)
+    } else if(pos == 0) {
+      l ++ this
+    } else {
+      this match {
+        case Cons(h, t) =>
+          Cons(h, t.insertAt(pos-1, l))
+        case Nil() =>
+          l
+      }
+    }
+  }
+
+  def replaceAt(pos: Int, l: List[T]): List[T] = {
+    if(pos < 0) {
+      replaceAt(size + pos, l)
+    } else if(pos == 0) {
+      l ++ this.drop(l.size)
+    } else {
+      this match {
+        case Cons(h, t) =>
+          Cons(h, t.replaceAt(pos-1, l))
+        case Nil() =>
+          l
+      }
+    }
+  }
+
+  def rotate(s: Int): List[T] = {
+    if (s < 0) {
+      rotate(size+s)
+    } else {
+      val s2 = s % size
+      drop(s2) ++ take(s2)
+    }
+  }
+
+}
+
+@library
+object ListOps {
+  def flatten[T](ls: List[List[T]]): List[T] = ls match {
+    case Cons(l, t) => l ++ flatten(t)
+    case Nil() => Nil()
+  }
 }