diff --git a/src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java b/src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java
index dc45b9fc..ed69924a 100644
--- a/src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java
+++ b/src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java
@@ -1,781 +1,788 @@
-/*
- This file is part of Subsonic.
-
- Subsonic 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 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see .
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.androidapp.service;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.params.ConnManagerParams;
-import org.apache.http.conn.params.ConnPerRouteBean;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.scheme.SocketFactory;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
-import org.apache.http.protocol.HttpContext;
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.util.Log;
-import android.util.Xml;
-import net.sourceforge.subsonic.androidapp.R;
-import net.sourceforge.subsonic.androidapp.domain.Indexes;
-import net.sourceforge.subsonic.androidapp.domain.JukeboxStatus;
-import net.sourceforge.subsonic.androidapp.domain.Lyrics;
-import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
-import net.sourceforge.subsonic.androidapp.domain.MusicFolder;
-import net.sourceforge.subsonic.androidapp.domain.Playlist;
-import net.sourceforge.subsonic.androidapp.domain.SearchCritera;
-import net.sourceforge.subsonic.androidapp.domain.SearchResult;
-import net.sourceforge.subsonic.androidapp.domain.ServerInfo;
-import net.sourceforge.subsonic.androidapp.domain.Version;
-import net.sourceforge.subsonic.androidapp.service.parser.AlbumListParser;
-import net.sourceforge.subsonic.androidapp.service.parser.ErrorParser;
-import net.sourceforge.subsonic.androidapp.service.parser.IndexesParser;
-import net.sourceforge.subsonic.androidapp.service.parser.JukeboxStatusParser;
-import net.sourceforge.subsonic.androidapp.service.parser.LicenseParser;
-import net.sourceforge.subsonic.androidapp.service.parser.LyricsParser;
-import net.sourceforge.subsonic.androidapp.service.parser.MusicDirectoryParser;
-import net.sourceforge.subsonic.androidapp.service.parser.MusicFoldersParser;
-import net.sourceforge.subsonic.androidapp.service.parser.PlaylistParser;
-import net.sourceforge.subsonic.androidapp.service.parser.PlaylistsParser;
-import net.sourceforge.subsonic.androidapp.service.parser.RandomSongsParser;
-import net.sourceforge.subsonic.androidapp.service.parser.SearchResult2Parser;
-import net.sourceforge.subsonic.androidapp.service.parser.SearchResultParser;
-import net.sourceforge.subsonic.androidapp.service.parser.VersionParser;
-import net.sourceforge.subsonic.androidapp.service.ssl.SSLSocketFactory;
-import net.sourceforge.subsonic.androidapp.service.ssl.TrustSelfSignedStrategy;
-import net.sourceforge.subsonic.androidapp.util.CancellableTask;
-import net.sourceforge.subsonic.androidapp.util.Constants;
-import net.sourceforge.subsonic.androidapp.util.FileUtil;
-import net.sourceforge.subsonic.androidapp.util.ProgressListener;
-import net.sourceforge.subsonic.androidapp.util.Util;
-
-/**
- * @author Sindre Mehus
- */
-public class RESTMusicService implements MusicService {
-
- private static final String TAG = RESTMusicService.class.getSimpleName();
-
- private static final int SOCKET_CONNECT_TIMEOUT = 10 * 1000;
- private static final int SOCKET_READ_TIMEOUT_DEFAULT = 10 * 1000;
- private static final int SOCKET_READ_TIMEOUT_DOWNLOAD = 30 * 1000;
- private static final int SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS = 60 * 1000;
- private static final int SOCKET_READ_TIMEOUT_GET_PLAYLIST = 60 * 1000;
-
- // Allow 20 seconds extra timeout per MB offset.
- private static final double TIMEOUT_MILLIS_PER_OFFSET_BYTE = 20000.0 / 1000000.0;
-
- /**
- * URL from which to fetch latest versions.
- */
- private static final String VERSION_URL = "http://subsonic.org/backend/version.view";
-
- private static final int HTTP_REQUEST_MAX_ATTEMPTS = 5;
- private static final long REDIRECTION_CHECK_INTERVAL_MILLIS = 60L * 60L * 1000L;
-
- private final DefaultHttpClient httpClient;
- private long redirectionLastChecked;
- private int redirectionNetworkType = -1;
- private String redirectFrom;
- private String redirectTo;
- private final ThreadSafeClientConnManager connManager;
-
- public RESTMusicService() {
-
- // Create and initialize default HTTP parameters
- HttpParams params = new BasicHttpParams();
- ConnManagerParams.setMaxTotalConnections(params, 20);
- ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(20));
- HttpConnectionParams.setConnectionTimeout(params, SOCKET_CONNECT_TIMEOUT);
- HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_DEFAULT);
-
- // Turn off stale checking. Our connections break all the time anyway,
- // and it's not worth it to pay the penalty of checking every time.
- HttpConnectionParams.setStaleCheckingEnabled(params, false);
-
- // Create and initialize scheme registry
- SchemeRegistry schemeRegistry = new SchemeRegistry();
- schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- schemeRegistry.register(new Scheme("https", createSSLSocketFactory(), 443));
-
- // Create an HttpClient with the ThreadSafeClientConnManager.
- // This connection manager must be used if more than one thread will
- // be using the HttpClient.
- connManager = new ThreadSafeClientConnManager(params, schemeRegistry);
- httpClient = new DefaultHttpClient(connManager, params);
- }
-
- private SocketFactory createSSLSocketFactory() {
- try {
- return new SSLSocketFactory(new TrustSelfSignedStrategy(), SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- } catch (Throwable x) {
- Log.e(TAG, "Failed to create custom SSL socket factory, using default.", x);
- return org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory();
- }
- }
-
- @Override
- public void ping(Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "ping", null);
- try {
- new ErrorParser(context).parse(reader);
- XmlPullParser parser;
- parser = Xml.newPullParser();
- parser.setInput(reader);
- String version = parser.getAttributeValue(null, "version");
- if (version != null) {
- Util.setServerRestVersion(context, new Version(version));
- }
- } finally {
- Util.close(reader);
- }
- }
-
- @Override
- public boolean isLicenseValid(Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "getLicense", null);
- try {
- ServerInfo serverInfo = new LicenseParser(context).parse(reader);
- return serverInfo.isLicenseValid();
- } finally {
- Util.close(reader);
- }
- }
-
- public List getMusicFolders(Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "getMusicFolders", null);
- try {
- return new MusicFoldersParser(context).parse(reader, progressListener);
- } finally {
- Util.close(reader);
- }
- }
-
- public void star(String id, Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "star", null, "id", id);
- try {
- new ErrorParser(context).parse(reader);
- } finally {
- Util.close(reader);
- }
- }
-
- public void unstar(String id, Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "unstar", null, "id", id);
- try {
- new ErrorParser(context).parse(reader);
- } finally {
- Util.close(reader);
- }
- }
-
- @Override
- public Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
- Indexes cachedIndexes = readCachedIndexes(context, musicFolderId);
- long lastModified = cachedIndexes == null ? 0L : cachedIndexes.getLastModified();
-
- List parameterNames = new ArrayList();
- List