diff --git a/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 b/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64
index 4e1067210..a54073750 100755
Binary files a/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 and b/python_apps/pypo/liquidsoap_bin/liquidsoap-natty-amd64 differ
diff --git a/python_apps/pypo/liquidsoap_scripts/library/Makefile b/python_apps/pypo/liquidsoap_scripts/library/Makefile
deleted file mode 100644
index d10777180..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-SUBDIRS = tests
-DISTFILES = $(wildcard *.in) Makefile ask-liquidsoap.rb ask-liquidsoap.pl \
-	    $(wildcard *.liq) extract-replaygain
-
-top_srcdir = ..
-include $(top_srcdir)/Makefile.rules
diff --git a/python_apps/pypo/liquidsoap_scripts/library/ask-liquidsoap.pl b/python_apps/pypo/liquidsoap_scripts/library/ask-liquidsoap.pl
deleted file mode 100755
index a2f10206e..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/ask-liquidsoap.pl
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict ;
-use Net::Telnet ;
-
-my $telnet = new Net::Telnet ( Timeout=>10, Errmode=>'die', Port=>1234) ;
-$telnet->open('localhost') ;
-
-die "Usage: $0 <command>\n" unless @ARGV ;
-$telnet->print($ARGV[0]) ;
-my ($output,$end) = $telnet->waitfor('/END$/') ;
-print $output;
diff --git a/python_apps/pypo/liquidsoap_scripts/library/ask-liquidsoap.rb b/python_apps/pypo/liquidsoap_scripts/library/ask-liquidsoap.rb
deleted file mode 100755
index 2dc65e6f8..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/ask-liquidsoap.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/ruby
-
-require 'net/telnet'
-
-liq_host = "localhost"
-liq_port = 1234
-
-conn = Net::Telnet::new("Host" => liq_host, "Port" => liq_port)
-
-conn.puts(ARGV[0])
-conn.waitfor("Match" => /^END$/) do |data|
-  puts data.sub(/\nEND\n/,"")
-end
diff --git a/python_apps/pypo/liquidsoap_scripts/library/externals.liq b/python_apps/pypo/liquidsoap_scripts/library/externals.liq
index 78f48197f..a3b1a2bc3 100644
--- a/python_apps/pypo/liquidsoap_scripts/library/externals.liq
+++ b/python_apps/pypo/liquidsoap_scripts/library/externals.liq
@@ -1,13 +1,5 @@
 # Decoders, enabled when the binary is detected and the os is not Win32.
 
-# Get_mime is not always defined
-# so we define a default in this case..
-my_get_mime = fun (_) -> ""
-%ifdef get_mime
-my_get_mime = get_mime
-%endif
-get_mime = my_get_mime
-
 %ifdef add_decoder
 # Enable external FLAC decoders. Requires flac binary
 # in the path for audio decoding and metaflac binary for 
@@ -164,6 +156,7 @@ end
 # Standard function for displaying metadata.
 # Shows artist and title, using "Unknown" when a field is empty.
 # @param m Metadata packet to be displayed.
+# @category String
 def string_of_metadata(m)
   artist = m["artist"]
   title  = m["title"]
@@ -177,6 +170,7 @@ end
 # @param ~position Position of the text (top|middle|bottom).
 # @param ~font     Font used (xfontsel is your friend...)
 # @param ~display  Function used to display a metadata packet.
+# @category Source / Track Processing
 def osd_metadata(~color="green",~position="top",
         ~font="-*-courier-*-r-*-*-*-240-*-*-*-*-*-*",
         ~display=string_of_metadata,
@@ -195,6 +189,7 @@ end
 # @param ~time    Timeout in milliseconds.
 # @param ~display Function used to display a metadata packet.
 # @param ~title   Title of the notification message.
+# @category Source / Track Processing
 def notify_metadata(~urgency="low",~icon="stock_smiley-22",~time=3000,
            ~display=string_of_metadata,
            ~title="Liquidsoap: new track",s)
@@ -211,6 +206,7 @@ end
 # @param ~restart_on_error restart on exit with error.
 # @param ~buffer Duration of the pre-buffered data.
 # @param ~max Maximum duration of the buffered data.
+# @category Source / Input
 def input.mplayer(~id="input.mplayer",
          ~restart=true,~restart_on_error=false,
          ~buffer=0.2,~max=10.,s) =
diff --git a/python_apps/pypo/liquidsoap_scripts/library/extract-replaygain b/python_apps/pypo/liquidsoap_scripts/library/extract-replaygain
deleted file mode 100755
index 20afbc179..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/extract-replaygain
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict ;
-
-my $file = $ARGV[0] || die ;
-
-sub test_mime {
-  my $file = shift ;
-  if (`which file`) {
-    return `file -b --mime-type "$file"`;
-  }
-}
-
-if (($file =~ /\.mp3$/i) || (test_mime($file) =~ /audio\/mpeg/))  {
-
-  if (`which mp3gain`) {
-
-    my $out = `mp3gain -q "$file" 2> /dev/null` ;
-    $out =~ /Recommended "Track" dB change: (.*)$/m || die ;
-    print "$1 dB\n" ;
-
-  } else {
-
-    print STDERR "Cannot find mp3gain binary!\n";
-
-  }
-
-} elsif (($file =~ /\.ogg$/i) || (test_mime($file) =~ /application\/ogg/)) {
-
-  if ((`which vorbisgain`) && (`which ogginfo`)) {
-
-    system("vorbisgain -q -f \"$file\" 2>/dev/null >/dev/null") ;
-    my $info = `ogginfo "$file"` ;
-    $info =~ /REPLAYGAIN_TRACK_GAIN=(.*) dB/ || die ;
-    print "$1 dB\n" ;
-
-  } else {
-
-    print STDERR "Cannot find vorbisgain or ogginfo!\n";
-
-  }
-
-} elsif (($file =~ /\.flac$/i) || (test_mime($file) =~ /audio\/x-flac/)) {
-
-  if (`which metaflac`) {
-
-    my $info = `metaflac --show-tag=REPLAYGAIN_TRACK_GAIN "$file"` ;
-    $info =~ /REPLAYGAIN_TRACK_GAIN=(.*) dB/;
-    if (defined($1)) {
-
-        print "$1 dB\n" ;
-
-    } else {
-
-      system("metaflac --add-replay-gain \"$file\" \
-              2>/dev/null >/dev/null") ;
-      $info = `metaflac --show-tag=REPLAYGAIN_TRACK_GAIN "$file"` ;
-      $info =~ /REPLAYGAIN_TRACK_GAIN=(.*) dB/ || die "Error in $file" ;
-      print "$1 dB\n" ;
-
-    }
-
-  } else {
-
-    print STDERR "Cannot find metaflac!\n";
-
-  }
-
-} else {
-
-  print STDERR "File format not supported...\n";
-
-}
diff --git a/python_apps/pypo/liquidsoap_scripts/library/http.liq b/python_apps/pypo/liquidsoap_scripts/library/http.liq
new file mode 100644
index 000000000..109baf41e
--- /dev/null
+++ b/python_apps/pypo/liquidsoap_scripts/library/http.liq
@@ -0,0 +1,43 @@
+# Set of HTTP utils.
+
+%include "http_codes.liq"
+
+# Create a HTTP response string
+# @category Interaction
+# @param ~protocol HTTP protocol used.
+# @param ~code Response code.
+# @param ~headers Response headers.
+# @param ~data Response data
+def http_response(~protocol="HTTP/1.1",
+                  ~code=200,
+                  ~headers=[],
+                  ~data="") = 
+  status = http_codes[string_of(code)]
+  # Set content-length if needed and not set by the
+  # user.
+  headers = 
+    if data != "" and 
+       not list.mem_assoc("Content-Length",headers) 
+    then
+      list.append([("Content-Length",
+                    "#{string.length(data)}")],
+                  headers)
+    else
+      headers
+    end
+  headers = list.map(fun (x) -> "#{fst(x)}: #{snd(x)}",headers)
+  headers = string.concat(separator="\r\n",headers)
+  # If no headers are provided, we should avoid
+  # having an empty line for them. Therefore, we also
+  # conditionally add the final \r\n here.
+  headers =
+    if headers != "" then
+      "#{headers}\r\n"
+    else
+      headers
+    end
+  "#{protocol} #{code} #{status}\r\n\
+   #{headers}\
+   \r\n\
+   #{data}"
+end
diff --git a/python_apps/pypo/liquidsoap_scripts/library/http_codes.liq b/python_apps/pypo/liquidsoap_scripts/library/http_codes.liq
new file mode 100644
index 000000000..a2359a18e
--- /dev/null
+++ b/python_apps/pypo/liquidsoap_scripts/library/http_codes.liq
@@ -0,0 +1,304 @@
+# List of HTTP codes. Stolen from en.wikipedia.org..
+
+# List of HTTP response codes and statuses.
+# @category Interaction
+def http_codes = [
+("100","Continue"),
+#This means that the server has received the request headers, and that the client
+#should proceed to send the request body (in the case of a request for which a
+#body needs to be sent; for example, a POST request). If the request body is
+#large, sending it to a server when a request has already been rejected based
+#upon inappropriate headers is inefficient. To have a server check if the request
+#could be accepted based on the request's headers alone, a client must send
+#Expect: 100-continue as a header in its initial request and check if a 100
+#Continue status code is received in response before continuing (or receive 417
+#Expectation Failed and not continue).
+
+("101","Switching Protocols"),
+#This means the requester has asked the server to switch protocols and the server
+#is acknowledging that it will do so.
+
+("102","Processing"),
+#As a WebDAV request may contain many sub-requests involving file operations, it
+#may take a long time to complete the request. This code indicates that the
+#server has received and is processing the request, but no response is available
+#yet. This prevents the client from timing out and assuming the request was
+#lost.
+
+("122","Request-URI too long"),
+#This is a non-standard IE7-only code which means the URI is longer than a
+#maximum of 2083 characters. (See code 414.),
+
+#2xx Success
+#This class of status codes indicates the action requested by the client was
+#received, understood, accepted and processed successfully.
+
+("200","OK"),
+#Standard response for successful HTTP requests. The actual response will depend
+#on the request method used. In a GET request, the response will contain an
+#entity corresponding to the requested resource. In a POST request the response
+#will contain an entity describing or containing the result of the action.
+
+("201","Created"),
+#The request has been fulfilled and resulted in a new resource being created.
+
+("202","Accepted"),
+#The request has been accepted for processing, but the processing has not been
+#completed. The request might or might not eventually be acted upon, as it might
+#be disallowed when processing actually takes place.
+
+("203","Non-Authoritative Information"),
+#The server successfully processed the request, but is returning information that
+#may be from another source.
+
+("204","No Content"),
+#The server successfully processed the request, but is not returning any
+#content.
+
+("205","Reset Content"),
+#The server successfully processed the request, but is not returning any content.
+#Unlike a 204 response, this response requires that the requester reset the
+#document view.
+
+("206","Partial Content"),
+#The server is delivering only part of the resource due to a range header sent by
+#the client. The range header is used by tools like wget to enable resuming of
+#interrupted downloads, or split a download into multiple simultaneous
+#streams.
+
+("207","Multi-Status"),
+#The message body that follows is an XML message and can contain a number of
+#separate response codes, depending on how many sub-requests were made.
+
+("226","IM Used"),
+#The server has fulfilled a GET request for the resource, and the response is a
+#representation of the result of one or more instance-manipulations applied to
+#the current instance. 
+
+#3xx Redirection
+#The client must take additional action to complete the request.
+#This class of status code indicates that further action needs to be taken by the
+#user agent in order to fulfil the request. The action required may be carried
+#out by the user agent without interaction with the user if and only if the
+#method used in the second request is GET or HEAD. A user agent should not
+#automatically redirect a request more than five times, since such redirections
+#usually indicate an infinite loop.
+
+("300","Multiple Choices"),
+#Indicates multiple options for the resource that the client may follow. It, for
+#instance, could be used to present different format options for video, list
+#files with different extensions, or word sense disambiguation.
+
+("301","Moved Permanently"),
+#This and all future requests should be directed to the given URI.
+
+("302","Found"),
+#This is an example of industrial practice contradicting the standard.
+#HTTP/1.0 specification (RFC 1945) required the client to perform a temporary
+#redirect (the original describing phrase was "Moved Temporarily"), but
+#popular browsers implemented 302 with the functionality of a 303 See Other.
+#Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the
+#two behaviours. However, the majority of Web applications and frameworks
+#still[as of?] use the 302 status code as if it were the 303.[citation needed]
+
+("303","See Other"),
+#The response to the request can be found under another URI using a GET method.
+#When received in response to a POST (or PUT/DELETE), it should be assumed that
+#the server has received the data and the redirect should be issued with a
+#separate GET message.
+
+("304","Not Modified"),
+#Indicates the resource has not been modified since last requested. Typically,
+#the HTTP client provides a header like the If-Modified-Since header to provide a
+#time against which to compare. Using this saves bandwidth and reprocessing on
+#both the server and client, as only the header data must be sent and received in
+#comparison to the entirety of the page being re-processed by the server, then
+#sent again using more bandwidth of the server and client.
+
+("305","Use Proxy"),
+#Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly
+#handle responses with this status code, primarily for security reasons.
+
+("306","Switch Proxy"),
+#No longer used.
+
+("307","Temporary Redirect"),
+#In this occasion, the request should be repeated with another URI, but future
+#requests can still use the original URI. In contrast to 303, the request
+#method should not be changed when reissuing the original request. For instance,
+#a POST request must be repeated using another POST request.
+
+#4xx Client Error
+#The 4xx class of status code is intended for cases in which the client seems to
+#have erred. Except when responding to a HEAD request, the server should include
+#an entity containing an explanation of the error situation, and whether it is a
+#temporary or permanent condition. These status codes are applicable to any
+#request method. User agents should display any included entity to the user.
+#These are typically the most common error codes encountered while online.
+
+("400","Bad Request"),
+#The request cannot be fulfilled due to bad syntax.
+
+("401","Unauthorized"),
+#Similar to 403 Forbidden, but specifically for use when authentication is
+#possible but has failed or not yet been provided. The response must include a
+#WWW-Authenticate header field containing a challenge applicable to the requested
+#resource. See Basic access authentication and Digest access authentication.
+
+("402","Payment Required"),
+#Reserved for future use. The original intention was that this code might be
+#used as part of some form of digital cash or micropayment scheme, but that has
+#not happened, and this code is not usually used. As an example of its use,
+#however, Apple's MobileMe service generates a 402 error ("httpStatusCode:402" in
+#the Mac OS X Console log) if the MobileMe account is delinquent.
+
+("403","Forbidden"),
+#The request was a legal request, but the server is refusing to respond to it.
+#Unlike a 401 Unauthorized response, authenticating will make no difference.
+
+("404","Not Found"),
+#The requested resource could not be found but may be available again in the
+#future. Subsequent requests by the client are permissible.
+
+("405","Method Not Allowed"),
+#A request was made of a resource using a request method not supported by that
+#resource; for example, using GET on a form which requires data to be
+#presented via POST, or using PUT on a read-only resource.
+
+("406","Not Acceptable"),
+#The requested resource is only capable of generating content not acceptable
+#according to the Accept headers sent in the request.
+
+("407","Proxy Authentication Required"),
+
+("408","Request Timeout"),
+#The server timed out waiting for the request. According to W3 HTTP
+#specifications: "The client did not produce a request within the time that the
+#server was prepared to wait. The client MAY repeat the request without
+#modifications at any later time."
+
+("409","Conflict"),
+#Indicates that the request could not be processed because of conflict in the
+#request, such as an edit conflict.
+
+("410","Gone"),
+#Indicates that the resource requested is no longer available and will not be
+#available again. This should be used when a resource has been intentionally
+#removed and the resource should be purged. Upon receiving a 410 status code, the
+#client should not request the resource again in the future. Clients such as
+#search engines should remove the resource from their indices. Most use cases do
+#not require clients and search engines to purge the resource, and a "404 Not
+#Found" may be used instead.
+
+("411","Length Required"),
+#The request did not specify the length of its content, which is required by the
+#requested resource.
+
+("412","Precondition Failed"),
+#The server does not meet one of the preconditions that the requester put on the
+#request.
+
+("413","Request Entity Too Large"),
+#The request is larger than the server is willing or able to process.
+
+("414","Request-URI Too Long"),
+#The URI provided was too long for the server to process.
+
+("415","Unsupported Media Type"),
+#The request entity has a media type which the server or resource does not
+#support. For example, the client uploads an image as image/svg+xml, but the
+#server requires that images use a different format.
+
+("416","Requested Range Not Satisfiable"),
+#The client has asked for a portion of the file, but the server cannot supply
+#that portion. For example, if the client asked for a part of the file that
+#lies beyond the end of the file.
+
+("417","Expectation Failed"),
+#The server cannot meet the requirements of the Expect request-header field.
+
+("418","I'm a teapot"),
+#This code was defined in 1998 as one of the traditional IETF April Fools' jokes,
+#in RFC 2324, Hyper Text Coffee Pot Control Protocol, and is not expected to be
+#implemented by actual HTTP servers.
+
+("422","Unprocessable Entity"),
+#The request was well-formed but was unable to be followed due to semantic
+#errors.
+
+("423","Locked"),
+#The resource that is being accessed is locked.
+
+("424","Failed Dependency"),
+#The request failed due to failure of a previous request (e.g. a PROPPATCH).
+
+("425","Unordered Collection"),
+#Defined in drafts of "WebDAV Advanced Collections Protocol", but not present
+#in "Web Distributed Authoring and Versioning (WebDAV) Ordered Collections
+#Protocol".
+
+("426","Upgrade Required"),
+#The client should switch to a different protocol such as TLS/1.0.
+
+("444","No Response"),
+#A Nginx HTTP server extension. The server returns no information to the client
+#and closes the connection (useful as a deterrent for malware).
+
+("449","Retry With"),
+#A Microsoft extension. The request should be retried after performing the
+#appropriate action.
+
+("450","Blocked by Windows Parental Controls"),
+#A Microsoft extension. This error is given when Windows Parental Controls are
+#turned on and are blocking access to the given webpage.
+
+("499","Client Closed Request"),
+#An Nginx HTTP server extension. This code is introduced to log the case when the
+#connection is closed by client while HTTP server is processing its request,
+#making server unable to send the HTTP header back.
+
+#5xx Server Error
+#The server failed to fulfill an apparently valid request.
+#Response status codes beginning with the digit "5" indicate cases in which the
+#server is aware that it has encountered an error or is otherwise incapable of
+#performing the request. Except when responding to a HEAD request, the server
+#should include an entity containing an explanation of the error situation, and
+#indicate whether it is a temporary or permanent condition. Likewise, user agents
+#should display any included entity to the user. These response codes are
+#applicable to any request method.
+
+("500","Internal Server Error"),
+#A generic error message, given when no more specific message is suitable.
+
+("501","Not Implemented"),
+#The server either does not recognise the request method, or it lacks the ability
+#to fulfill the request.
+
+("502","Bad Gateway"),
+#The server was acting as a gateway or proxy and received an invalid response
+#from the upstream server.
+
+("503","Service Unavailable"),
+#The server is currently unavailable (because it is overloaded or down for
+#maintenance). Generally, this is a temporary state.
+
+("504","Gateway Timeout"),
+#The server was acting as a gateway or proxy and did not receive a timely
+#response from the upstream server.
+
+("505","HTTP Version Not Supported"),
+#The server does not support the HTTP protocol version used in the request.
+
+("506","Variant Also Negotiates"),
+#Transparent content negotiation for the request results in a circular
+#reference.
+
+("507","Insufficient Storage"),
+
+("509","Bandwidth Limit Exceeded"),
+#This status code, while used by many servers, is not specified in any RFCs.
+
+("510","Not Extended")
+#Further extensions to the request are required for the server to fulfill it.
+]
+end
diff --git a/python_apps/pypo/liquidsoap_scripts/library/lastfm.liq b/python_apps/pypo/liquidsoap_scripts/library/lastfm.liq
index 0886bf0a2..7b52c5b14 100644
--- a/python_apps/pypo/liquidsoap_scripts/library/lastfm.liq
+++ b/python_apps/pypo/liquidsoap_scripts/library/lastfm.liq
@@ -1,9 +1,4 @@
-
-dummy = fun () -> log("Lastfm/audioscrobbler support was not compiled.")
-
 %ifdef input.lastfm
-dummy = fun () -> ()
-
 # Utility to compose last.fm URIs.
 # @category String
 # @param ~user      Lastfm user
@@ -128,6 +123,3 @@ def lastfm.submit.full(
 end
 
 %endif
-
-dummy ()
-
diff --git a/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.gentoo.initd.in b/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.gentoo.initd.in
deleted file mode 100755
index 3281fe925..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.gentoo.initd.in
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/sbin/runscript
-
-user=@install_user@
-group=@install_group@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-confdir=@sysconfdir@/liquidsoap
-liquidsoap=@bindir@/liquidsoap
-rundir=@localstatedir@/run/liquidsoap
-
-depend() {
-  after net icecast
-}
-
-start() {
-  cd $confdir
-  for liq in *.liq ; do
-    if test $liq != '*.liq' ; then
-      ebegin "Starting $liq"
-      start-stop-daemon --start --quiet --pidfile $rundir/${liq%.liq}.pid \
-        --chuid $user:$group --exec $liquidsoap -- -d $confdir/$liq
-      eend $?
-    fi
-  done
-}
-
-stop() {
-  cd $rundir
-  for liq in *.pid ; do
-    if test $liq != '*.pid' ; then
-      ebegin "Stopping $liq"
-      start-stop-daemon --stop --quiet --pidfile $liq
-      eend $?
-    fi
-  done
-}
-
-restart() {
-  svc_stop
-  einfo "Sleeping 4 seconds ..."
-  sleep 4
-  svc_start
-}
diff --git a/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.initd.in b/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.initd.in
deleted file mode 100755
index 9b447a159..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.initd.in
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides:          liquidsoap
-# Required-Start:    $remote_fs $network $time
-# Required-Stop:     $remote_fs $network $time
-# Should-Start:
-# Should-Stop:
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Short-Description: Starts the liquidsoap daemon
-# Description:
-### END INIT INFO
-
-user=@install_user@
-group=@install_group@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-confdir=@sysconfdir@/liquidsoap
-liquidsoap=@bindir@/liquidsoap
-rundir=@localstatedir@/run/liquidsoap
-
-# Test if $rundir exists
-if [ ! -d $rundir ]; then
-  mkdir -p $rundir;
-  chown $user:$group $rundir
-fi
-
-case "$1" in
-  stop)
-    echo -n "Stopping channels: "
-    cd $rundir
-    for liq in *.pid ; do
-      if test $liq != '*.pid' ; then
-        echo -n "$liq "
-        start-stop-daemon --stop --quiet --pidfile $liq --retry 4
-      fi
-    done
-    echo "OK"
-    ;;
-
-  start)
-    echo -n "Starting channels: "
-    cd $confdir
-    for liq in *.liq ; do
-      if test $liq != '*.liq' ; then
-        echo -n "$liq "
-        start-stop-daemon --start --quiet --pidfile $rundir/${liq%.liq}.pid \
-          --chuid $user:$group --exec $liquidsoap -- -d $confdir/$liq
-      fi
-    done
-    echo "OK"
-    ;;
-
-  restart|force-reload)
-    $0 stop
-    $0 start
-    ;;
-
-  *)
-    echo "Usage: $0 {start|stop|restart|force-reload}"
-    exit 1
-    ;;
-esac
diff --git a/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.logrotate.in b/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.logrotate.in
deleted file mode 100644
index 9b154ae45..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/liquidsoap.logrotate.in
+++ /dev/null
@@ -1,15 +0,0 @@
-@localstatedir@/log/liquidsoap/*.log {
-  compress
-  rotate 5
-  size 300k
-  missingok
-  notifempty
-  sharedscripts
-  postrotate
-    for liq in @localstatedir@/run/liquidsoap/*.pid ; do
-      if test $liq != '@localstatedir@/run/liquidsoap/*.pid' ; then
-        start-stop-daemon --stop --signal USR1 --quiet --pidfile $liq
-      fi
-    done
-  endscript
-}
diff --git a/python_apps/pypo/liquidsoap_scripts/library/liquidtts.in b/python_apps/pypo/liquidsoap_scripts/library/liquidtts.in
deleted file mode 100644
index c7e2f906f..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/liquidtts.in
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# This script is called from liquidsoap for generating a file
-# for "say:voice/text" URIs.
-# Usage: liquidtts text output_file voice
-
-echo $1 | @TEXT2WAVE@ -f 44100 > $2.tmp.wav && @SOX@ 2> /dev/null > /dev/null
-return=$?
-@RM@ $2.tmp.wav
-@NORMALIZE@ $2 2> /dev/null > /dev/null
-exit $return
diff --git a/python_apps/pypo/liquidsoap_scripts/library/pervasives.liq b/python_apps/pypo/liquidsoap_scripts/library/pervasives.liq
index 93ad95202..bd894766b 100644
--- a/python_apps/pypo/liquidsoap_scripts/library/pervasives.liq
+++ b/python_apps/pypo/liquidsoap_scripts/library/pervasives.liq
@@ -3,3 +3,5 @@
 %include "shoutcast.liq"
 %include "lastfm.liq"
 %include "flows.liq"
+%include "http.liq"
+%include "video_text.liq"
\ No newline at end of file
diff --git a/python_apps/pypo/liquidsoap_scripts/library/shoutcast.liq b/python_apps/pypo/liquidsoap_scripts/library/shoutcast.liq
index e7dc167c9..1cdc2fbd9 100644
--- a/python_apps/pypo/liquidsoap_scripts/library/shoutcast.liq
+++ b/python_apps/pypo/liquidsoap_scripts/library/shoutcast.liq
@@ -4,14 +4,13 @@
 # @category Source / Output
 # @param ~id Output's ID
 # @param ~start Start output threads on operator initialization.
-# @param ~restart Restart output after a failure. By default, liquidsoap will stop if the output failed.
-# @param ~restart_delay Delay, in seconds, before attempting new connection, if restart is enabled.
 # @param ~user User for shout source connection. Useful only in special cases, like with per-mountpoint users.
 # @param ~icy_reset Reset shoutcast source buffer upon connecting (necessary for NSV).
 # @param ~dumpfile Dump stream to file, for debugging purpose. Disabled if empty.
 # @param ~fallible Allow the child source to fail, in which case the output will be (temporarily) stopped.
 # @param ~on_start Callback executed when outputting starts.
 # @param ~on_stop Callback executed when outputting stops.
+# @param ~on_error Callback executed when an error happens. If returned value is positive, connection wll be tried again after this amount of time (in seconds).
 # @param ~on_connect Callback executed when connection starts.
 # @param ~on_disconnect Callback executed when connection stops.
 # @param ~icy_metadata Send new metadata using the ICY protocol. One of: "guess", "true", "false"
@@ -20,7 +19,6 @@
 # @param s The source to output
 def output.shoutcast(
   ~id="output.shoutcast",~start=true,
-  ~restart=false,~restart_delay=3,
   ~host="localhost",~port=8000,
   ~user="source",~password="hackme",
   ~genre="Misc",~url="http://savonet.sf.net/",
@@ -29,7 +27,7 @@ def output.shoutcast(
   ~on_connect={()}, ~on_disconnect={()},
   ~aim="",~icq="",~irc="",~icy_reset=true,
   ~fallible=false,~on_start={()},~on_stop={()},
-  e,s) = 
+  ~on_error=fun(_)->3., e,s) = 
   icy_reset = if icy_reset then "1" else "0" end
   headers = [("icy-aim",aim),("icy-irc",irc),
              ("icy-icq",icq),("icy-reset",icy_reset)]
@@ -38,11 +36,10 @@ def output.shoutcast(
     id=id, headers=headers,
     start=start,icy_metadata=icy_metadata,
     on_connect=on_connect, on_disconnect=on_disconnect,
-    restart=restart, restart_delay=restart_delay,
     host=host, port=port, user=user, password=password,
     genre=genre, url=url, description="UNUSED",
     public=public, dumpfile=dumpfile,encoding="ISO-8859-1",
-    name=name, mount="/", protocol="icy",
+    name=name, mount="/", protocol="icy",on_error=on_error,
     fallible=fallible,on_start=on_start,on_stop=on_stop,
     s)
 end
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/BUG403.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/BUG403.liq
deleted file mode 100644
index c86eaac08..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/BUG403.liq
+++ /dev/null
@@ -1,21 +0,0 @@
-# This is the test for bug #403 from our old trac.
-#
-# Make a switch() declare itself ready and arrange to use it for the next
-# frame where it isn't ready anymore.
-#
-# Two switches A and B
-# A is only ready for a short period of time due to its predicates.
-# B reselects at the end of a frame just before A becomes unavailable
-# as a result, B has selected = A, attempts to stream it
-# but A finds itself not ready anymore.
-# In other words, B committed but A did not.
-
-r = ref false
-pred = { v=!r ; r:=false ; v }
-add_timeout(2.,{ r := true ; (-1.) })
-
-mixer = fallback(id="mixer", track_sensitive=false,
-  [at(pred, sine(duration=3.)), blank()])
-
-output.dummy(mixer)
-add_timeout(3.,{ print("TEST PASSED") ; shutdown() ; (-1.) })
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/LS268.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/LS268.liq
deleted file mode 100644
index 195a1d9a2..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/LS268.liq
+++ /dev/null
@@ -1,10 +0,0 @@
-# In LS-268 we realized that an incorrect assumption had
-# been made in code from LS-394, resulting in a crash in
-# case of source re-awakening.
-
-p = input.http("http://localhost:8000/nonexistent")
-o = output.dummy(fallible=true,p)
-
-add_timeout(2.,{ source.shutdown(o) ; (-1.) })
-add_timeout(3.,{ output.dummy(fallible=true,p) ; (-1.) })
-add_timeout(4.,{ shutdown() ; (-1.) })
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/LS354-1.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/LS354-1.liq
deleted file mode 100644
index 2e30612a4..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/LS354-1.liq
+++ /dev/null
@@ -1,11 +0,0 @@
-s = on_track(
-     fun(_)-> begin print("TEST PASSED") shutdown() end,
-     blank(duration=1.))
-
-r = ref false
-d = source.dynamic({ if !r then [s] else [] end })
-
-output.dummy(mksafe(d))
-
-add_timeout(2.,{r:=true;(-1.)})
-add_timeout(4.,{print("TEST FAILED");shutdown();(-1.)})
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/LS354-2.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/LS354-2.liq
deleted file mode 100644
index ff9ca3817..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/LS354-2.liq
+++ /dev/null
@@ -1,15 +0,0 @@
-s1 = fail()
-s2 = on_track(
-       fun(_)-> begin print("TEST PASSED") shutdown() end,
-       blank(duration=1.))
-
-r = ref 0
-d = source.dynamic({ if !r==1 then [s1]
-                     elsif !r==2 then [s2]
-                     else [] end })
-
-output.dummy(mksafe(d))
-
-add_timeout(2.,{r:=1;(-1.)})
-add_timeout(3.,{r:=2;(-1.)})
-add_timeout(5.,{print("TEST FAILED");shutdown();(-1.)})
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/LS460.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/LS460.liq
deleted file mode 100644
index 5c7e530f8..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/LS460.liq
+++ /dev/null
@@ -1,17 +0,0 @@
-# Scenario:
-#  Let foo start using q, then stop it, skip in q.
-#  When foo restarts it doesn't know that q isn't ready anymore,
-#  which can lead to a crash.
-
-q = once(sine(duration=10.))
-output.dummy(id="bar",mksafe(q))
-output.dummy(id="foo",fallback([amplify(1.,q),blank(duration=1.)]))
-
-def at(t,s)
-  add_timeout(t,{ignore(server.execute(s));(-1.)})
-end
-
-at(3.,"foo.stop")
-at(4.,"bar.skip")
-at(5.,"foo.start")
-add_timeout(6.,{print("TEST PASSED");shutdown();(-1.)})
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/LS503.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/LS503.liq
deleted file mode 100644
index 49dadf1a4..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/LS503.liq
+++ /dev/null
@@ -1,13 +0,0 @@
-# In LS-503 we realized that a source may throw an
-# exception during output_get_ready call in the initial
-# main phase. This code reproduces the issue by throwing
-# an exception in output.icecast.
-
-# Reopen stderr to /dev/null to
-# disable printing expected exception
-reopen.stderr("/dev/null")
-
-p = input.http("http://localhost:8000/nonexistent")
-o = output.icecast(%wav,fallible=true,host="nonexistent",
-                    mount="test",p)
-
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/Makefile b/python_apps/pypo/liquidsoap_scripts/library/tests/Makefile
deleted file mode 100644
index e9cda96a8..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-
-DISTFILES = Makefile $(wildcard *.liq) $(wildcard *.pl)
-
-top_srcdir = ../..
-include $(top_srcdir)/Makefile.rules
-
-test:
-	@for i in $(wildcard *.liq) ; do \
-	  echo -n "$$i... " ; $(top_srcdir)/src/liquidsoap -q - < ./$$i | head -n 1 ; \
-	done
-	@echo -n "type_errors.pl... " ; \
-	  if (./type_errors.pl > /dev/null 2> /dev/null) ; then \
-	    echo "TEST PASSED (check manually the prettiness of messages)" ; \
-      else \
-	    echo "TEST FAILED" ; \
-	  fi
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/eval.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/eval.liq
deleted file mode 100644
index 6a930daff..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/eval.liq
+++ /dev/null
@@ -1,43 +0,0 @@
-count = ref 1
-fail = ref false
-
-def echo(s)
-  # system("echo "^quote(s))
-  if s != string_of(!count) then
-    fail := true
-  end
-  count := !count + 1
-  ()
-end
-
-def test(lbl,f)
-  if f() then echo(lbl) else echo("fail "^lbl) end
-end
-
-test("1",{ 1==1 })
-test("2",{ 1+1==2 })
-test("3",{ (-1)+2==1 })
-test("4",{ (-1)+2 <= 3*2 })
-test("5",{ true })
-test("6",{ true and true })
-test("7",{ 1==1 and 1==1 })
-test("8",{ (1==1) and (1==1) })
-test("9",{ true and (-1)+2 <= 3*2 })
-
-l = [ ("bla",""), ("bli","x"), ("blo","xx"), ("blu","xxx"), ("dix","10") ]
-echo(l["dix"])
-test("11",{ 2 == list.length(string.split(separator="",l["blo"])) })
-
-%ifdef foobarbaz
-  if = if is not a well-formed expression, and we do not care...
-%endif
-
-echo("1#{1+1}")
-echo(string_of(int_of_float(float_of_string(default=13.,"blah"))))
-
-f=fun(x)->x
-# Checking that the following is not recursive:
-f=fun(x)->f(x)
-echo(string_of(f(14)))
-
-if !fail then print("TEST FAILED") else print("TEST PASSED") end
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/type_errors.pl b/python_apps/pypo/liquidsoap_scripts/library/tests/type_errors.pl
deleted file mode 100755
index f832eaed7..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/type_errors.pl
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict ;
-
-my $liquidsoap = "../../src/liquidsoap";
-die unless -f $liquidsoap ;
-
-$liquidsoap = "$liquidsoap -c";
-
-sub section {
-  print "\n*** $_[0] ***\n\n" ;
-}
-
-sub incorrect {
-  my $expr = pop ;
-  print "Incorrect expression $expr...\n" ;
-  system "$liquidsoap '$expr'" ;
-  die unless (($?>>8)==1) ;
-  print "\n" ;
-}
-
-sub correct {
-  my $expr = pop ;
-  print "Correct expression $expr...\n" ;
-  system "$liquidsoap -i '$expr'" ;
-  die unless (($?>>8)==0) ;
-  print "\n";
-}
-
-section("BASIC");
-incorrect('[1]==["1"]');
-incorrect('1==["1"]');
-incorrect('1==(1,"1")');
-# In some of those examples the type error could be reported for a
-# sub-expression since we have location information.
-# With the concise error, it's still pretty good currently.
-incorrect('(1,1)==(1,"1")');
-incorrect('(1,1)==("1",1)');
-incorrect('1==request.create("")');
-incorrect('fun(x)->x(snd(x))');
-
-section("SUBTYPING");
-incorrect('(1:unit)');
-correct('((blank():source(1,1,1)):source(*,*,*))');
-incorrect('((blank():source(*,*,*)):source(1,1,1))');
-# Next one requires the inference of a subtype (fixed vs. variable arity)
-correct('audio_to_stereo(add([]))');
-
-section("CONSTRAINTS");
-incorrect('"bl"+"a"');
-incorrect('(fun(a,b)->a+b)==(fun(a,b)->a+b)');
-incorrect('fun(x)->x(x)'); # TODO is it an accident that we get same varname
-incorrect('def f(x) y=snd(x) y(x) end');
-
-section("LET GENERALIZATION");
-correct('def f(x) = y=x ; y end f(3)+snd(f((1,2)))');
-incorrect('def f(x) = y=x ; y end f(3)+"3"');
-
-section("ARGUMENTS");
-# The errors should be about the type of the param, not of the function.
-incorrect('1+"1"');
-# Also, a special simple error is expected for obvious labelling mistakes.
-incorrect('fallback(transitions=[],xxxxxxxxxxx=[])');
-incorrect('fallback(transitions=[],transitions=[])');
-
-section("FUNCTIONS");
-incorrect('fallback(transitions=[fun(~l)->1])');
-incorrect('fallback(transitions=[fun(~l=1)->1])');
-incorrect('fallback(transitions=[fun(x,y=blank())->y])');
-incorrect('fallback(transitions=[fun(x,y)->0])');
-correct('f=fallback(transitions=[fun(x,y,a=2)->x])');
-incorrect('fallback(transitions=[fun(x,y)->y+1])');
-correct('x=fun(f)->f(3) y=x(fun(f,u="1")->u)');
-
-section("CONTENT KIND");
-incorrect('output.file(%vorbis(stereo),"foo",mean(blank()))');
-incorrect('output.file(%vorbis(stereo),"foo",video.add_image(blank()))');
-incorrect('def f(x) = output.file(%vorbis(stereo),"",x) output.file(%vorbis(mono),"",x) end');
-incorrect('add([output.file(%vorbis(stereo),"",blank()),output.file(%vorbis(mono),"",blank())])');
-incorrect('add([mean(blank()),audio_to_stereo(add([]))])');
-
-print "Everything's good!\n" ;
diff --git a/python_apps/pypo/liquidsoap_scripts/library/tests/typing.liq b/python_apps/pypo/liquidsoap_scripts/library/tests/typing.liq
deleted file mode 100644
index 8162ebaed..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/tests/typing.liq
+++ /dev/null
@@ -1,112 +0,0 @@
-# Check these examples with: liquidsoap --no-libs -i -c typing.liq
-
-# TODO Throughout this file, parsing locations displayed in error messages
-#      are often much too inaccurate.
-
-# Check that some polymorphism is allowed.
-# id : (string,'a)->'a
-def id(a,b)
-  log(a)
-  b
-end
-ignore("bla"==id("bla","bla"))
-ignore(0==id("zero",0))
-
-# Reporting locations for the next error is non-trivial, because it is about
-# an instantiation of the type of id. The deep error doesn't have relevant 
-# information about why the int should be a string, the outer one has.
-# id(0,0)
-
-# Polymorphism is limited to outer generalizations, this is not system F.
-# apply : ((string)->'a)->'a
-def apply(f)
-  f("bla")
-  # f is not polymorphic, the following is forbidden:
-  # f(0)
-  # f(f)
-end
-
-# The level checks forbid abusive generalization.
-# id' : ('a)->'a
-def id'(x)
-  # If one isn't careful about levels/scoping, f2 gets the type ('a)->'b
-  # and so does twisted_id.
-  def f2(y)
-    x
-  end
-  f2(x)
-end
-
-# More errors...
-# 0=="0"
-# [3,""]
-
-# Subtyping, functions and lists.
-f1 = fun () -> 3
-f2 = fun (a=1) -> a
-
-# This is OK, l1 is a list of elements of type f1.
-l1 = [f1,f2]
-list.iter(fun (f) -> log(string_of(f())), l1)
-# Forbidden. Indeed, f1 doesn't accept any argument -- although f2 does.
-# Here the error message may even be too detailed since it goes back to the 
-# definition of l1 and requires that f1 has type (int)->int.
-# list.iter(fun (f) -> log(string_of(f(42))), l1)
-
-# Actually, this is forbidden too, but the reason is more complex...
-# The infered type for the function is ((int)->int)->unit,
-# and (int)->int is not a subtype of (?int)->int.
-# There's no most general answer here since (?int)->int is not a 
-# subtype of (int)->int either.
-# list.iter(fun (f) -> log(string_of(f(42))), [f2])
-
-# Unlike l1, this is not OK, since we don't leave open subtyping constraints
-# while infering types.
-# I hope we can make the inference smarter in the future, without obfuscating
-# the error messages too much.
-# The type error here shows the use of all the displayed positions:
-#  f1 has type t1, f2 has type t2, t1 should be <: t2
-# l2 = [ f2, f1 ]
-
-# An error where contravariance flips the roles of both sides..
-# [fun (x) -> x+1, fun (y) -> y^"."]
-
-# An error without much locations..
-# TODO An explaination about the missing label would help a lot here.
-# def f(f)
-#   f(output.icecast.vorbis)
-#   f(output.icecast.mp3)
-# end
-
-# This causes an occur-check error.
-# TODO The printing of the types breaks the sharing of one EVAR
-#  across two types. Here the sharing is actually the origin of the occur-check
-#  error. And it's not easy to understand..
-# omega = fun (x) -> x(x)
-
-# Now let's test ad-hoc polymorphism.
-
-echo = fun(x) -> system("echo #{quote(string_of(x))}")
-
-ignore("bla")
-ignore((1,3.12))
-ignore(1 + 1)
-ignore(1. + 2.14)
-
-# string is not a Num
-# echo("bl"+"a")
-
-ignore(1 <= 2)
-ignore((1,2) == (1,3))
-
-# float <> int
-# echo(1 == 2.)
-
-# source is not an Ord
-# echo(blank()==blank())
-
-def sum_eq(a,b)
-  a+b == a
-end
-
-print("TEST PASSED")
diff --git a/python_apps/pypo/liquidsoap_scripts/library/type_printing.liq b/python_apps/pypo/liquidsoap_scripts/library/type_printing.liq
deleted file mode 100644
index 805734b6d..000000000
--- a/python_apps/pypo/liquidsoap_scripts/library/type_printing.liq
+++ /dev/null
@@ -1,61 +0,0 @@
-# run this file through "liquidsoap -c -i"
-# to see if pretty printing looks pretty enough
-# for more checks, pass --twidth 78
-
-x = (blank() : source(2,3,4))
-pair = (x,x)
-x = (x,x)
-x = (x,x)
-x = (x,x)
-
-def output.shoutcast(
-  ~id="output.shoutcast",~start=true,
-  ~restart=false,~restart_delay=3,
-  ~host="localhost",~port=8000,
-  ~user="source",~password="hackme",
-  ~genre="Misc",~url="http://savonet.sf.net/",
-  ~name="OCaml Radio!",~public=true, ~format="",
-  ~dumpfile="", ~icy_metadata="guess",
-  ~on_connect={()}, ~on_disconnect={()},
-  ~aim="",~icq="",~irc="",~icy_reset=true,
-  ~fallible=false,~on_start={()},~on_stop={()},
-  e,s)
-=
-  42
-end
-
-x = (output.shoutcast,pair)
-
-def output.shoutcast(
-  ~id="output.shoutcast",~start=true,
-  ~restart=false,~restart_delay=3,
-  ~host="localhost",~port=8000,
-  ~user="source",~password="hackme",
-  ~genre="Misc",~url="http://savonet.sf.net/",
-  ~name="OCaml Radio!",~public=true, ~format="",
-  ~dumpfile="", ~icy_metadata="guess",
-  ~on_connect={()}, ~on_disconnect={()},
-  ~aim="",~icq="",~irc="",~icy_reset=true,
-  ~fallible=false,~on_start={()},~on_stop={()},
-  e,s)
-=
-  (pair,42)
-end
-
-def output.shoutcast(
-  ~id="output.shoutcast",~start=true,
-  ~restart=false,~restart_delay=3,
-  ~host="localhost",~port=8000,
-  ~user="source",~password="hackme",
-  ~genre="Misc",~url="http://savonet.sf.net/",
-  ~name="OCaml Radio!",~public=true, ~format="",
-  ~dumpfile="", ~icy_metadata="guess",
-  ~on_connect={()}, ~on_disconnect={()},
-  ~aim="",~icq="",~irc="",~icy_reset=true,
-  ~fallible=false,~on_start={()},~on_stop={()},
-  e,s)
-=
-  (blank() : source(3,0,0))
-end
-
-x = (output.shoutcast,blank())
diff --git a/python_apps/pypo/liquidsoap_scripts/library/utils.liq b/python_apps/pypo/liquidsoap_scripts/library/utils.liq
index a28e9c8d8..5967662f4 100644
--- a/python_apps/pypo/liquidsoap_scripts/library/utils.liq
+++ b/python_apps/pypo/liquidsoap_scripts/library/utils.liq
@@ -257,7 +257,7 @@ def test_process(command)
 end
 
 # Split an url of the form foo?arg=bar&arg2=bar2
-# into ("foo",[("arg","bar"),("arg2","bar2")]
+# into ("foo",[("arg","bar"),("arg2","bar2")]).
 # @category String
 # @param uri Url to split
 def url.split(uri) = 
@@ -278,11 +278,11 @@ def url.split(uri) =
 end
 
 # Register a server/telnet command to 
-# update a source's metadata. Returns 
+# update a source's metadata. Returns
 # a new source, which will receive the 
-# updated metadata. Semantics is the 
-# same as pre 1.0 insert_metadata operator, 
-# i.e. @insert key1="val1",key2="val2",..@
+# updated metadata. It behaves just like
+# the pre-1.0 insert_metadata() operator, 
+# i.e. insert key1="val1",key2="val2",...
 # @category Source / Track Processing
 # @param ~id Force the value of the source ID.
 def server.insert_metadata(~id="",s) = 
@@ -384,9 +384,17 @@ def read(~hide=false)
   s
 end
 
-file.mime_default = fun (_) -> ""
+# Dummy implementation of file.mime
+# @category System
+def file.mime_default(_)
+  ""
+end
 %ifdef file.mime
-file.mime_default = file.mime
+# Alias of file.mime (because it is available)
+# @category System
+def file.mime_default(file)
+ file.mime(file)
+end
 %endif
 
 # Generic mime test. First try to use file.mime if it exist.
@@ -678,9 +686,9 @@ end
 add_protocol("replay_gain", replaygain_protocol)
 
 # Enable replay gain metadata resolver. This resolver will
-# process any file decoded by liquidsoap and add a @replay_gain@
+# process any file decoded by liquidsoap and add a replay_gain
 # metadata when this value could be computed. For a finer-grained
-# replay gain processing, use the @replay_gain@ protocol.
+# replay gain processing, use the replay_gain protocol.
 # @category Liquidsoap
 # @param ~extract_replaygain The extraction program
 def enable_replaygain_metadata(
diff --git a/python_apps/pypo/liquidsoap_scripts/library/video_text.liq b/python_apps/pypo/liquidsoap_scripts/library/video_text.liq
new file mode 100644
index 000000000..b372a1f7b
--- /dev/null
+++ b/python_apps/pypo/liquidsoap_scripts/library/video_text.liq
@@ -0,0 +1,43 @@
+%ifdef video.add_text.gd
+# Add a scrolling line of text on video frames.
+# @param ~id       Force the value of the source ID.
+# @param ~color    Text color (in 0xRRGGBB format).
+# @param ~cycle    Cycle text.
+# @param ~font     Path to ttf font file.
+# @param ~metadata Change text on a particular metadata \
+#                  (empty string means disabled).
+# @param ~size     Font size.
+# @param ~speed    Speed in pixels per second (0 means no scrolling).
+# @param ~x        x offset (negative means from right).
+# @param ~y        y offset (negative means from bottom).
+# @param text      Text to display.
+def video.add_text(~id="",~color=16777215,~cycle=true,
+                   ~font=configure.default_font,
+                   ~metadata="",~size=18,~speed=70,~x=-1,~y=-5,
+                   text,source)
+  video.add_text.gd(id=id,color=color,cycle=cycle,font=font,metadata=metadata,
+                    size=size,speed=speed,x=x,y=y,text,source)
+end
+%endif
+
+%ifdef video.add_text.sdl
+# Add a scrolling line of text on video frames.
+# @param ~id       Force the value of the source ID.
+# @param ~color    Text color (in 0xRRGGBB format).
+# @param ~cycle    Cycle text.
+# @param ~font     Path to ttf font file.
+# @param ~metadata Change text on a particular metadata \
+#                  (empty string means disabled).
+# @param ~size     Font size.
+# @param ~speed    Speed in pixels per second (0 means no scrolling).
+# @param ~x        x offset (negative means from right).
+# @param ~y        y offset (negative means from bottom).
+# @param text      Text to display.
+def video.add_text(~id="",~color=16777215,~cycle=true,
+                   ~font=configure.default_font,
+                   ~metadata="",~size=18,~speed=70,~x=-1,~y=-5,
+                   text,source)
+  video.add_text.sdl(id=id,color=color,cycle=cycle,font=font,metadata=metadata,
+                     size=size,speed=speed,x=x,y=y,text,source)
+end
+%endif
diff --git a/python_apps/pypo/liquidsoap_scripts/ls_lib.liq b/python_apps/pypo/liquidsoap_scripts/ls_lib.liq
index 1c2f0dafd..c59a211f0 100644
--- a/python_apps/pypo/liquidsoap_scripts/ls_lib.liq
+++ b/python_apps/pypo/liquidsoap_scripts/ls_lib.liq
@@ -49,8 +49,6 @@ def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, de
                     password = pass,
                     mount = mount_point,
                     fallible = true,
-                    restart = true,
-                    restart_delay = 5,
                     url = url,
                     description = description,
                     genre = genre,
@@ -132,8 +130,6 @@ def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, de
                     port = port,
                     password = pass,
                     fallible = true,
-                    restart = true,
-                    restart_delay = 5,
                     url = !url_ref,
                     genre = !genre_ref,
                     name = !description_ref,
diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq
index d4c4f08ed..1ea328c86 100644
--- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq
+++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq
@@ -51,7 +51,7 @@ add_skip_command(s)
 s = map_metadata(append_title, s)
 
 if output_sound_device then
-    ignore(output.alsa(s))
+    ignore(out(s))
 end
 
 if s1_output != "disabled" then